2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-22 18:17:07 +00:00
vinyldns/modules/portal/test/controllers/LdapAuthenticatorSpec.scala

709 lines
26 KiB
Scala
Raw Normal View History

2018-07-27 10:18:29 -04:00
/*
* Copyright 2018 Comcast Cable Communications Management, LLC
*
* 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.
*/
package controllers
import cats.effect.IO
2018-07-27 10:18:29 -04:00
import javax.naming.NamingEnumeration
import javax.naming.directory._
import controllers.LdapAuthenticator.{ContextCreator, LdapByDomainAuthenticator}
import org.specs2.mock.Mockito
import org.specs2.mock.mockito.ArgumentCapture
import org.specs2.mutable.Specification
import play.api.{Configuration, Environment}
import vinyldns.core.health.HealthCheck._
import vinyldns.core.domain.membership.User
import vinyldns.core.health.HealthCheck.HealthCheckError
2018-07-27 10:18:29 -04:00
class LdapAuthenticatorSpec extends Specification with Mockito {
case class Mocks(
contextCreator: ContextCreator,
context: DirContext,
searchResults: NamingEnumeration[SearchResult],
searchNext: SearchResult,
byDomainAuthenticator: LdapByDomainAuthenticator,
attributes: Attributes
)
2018-07-27 10:18:29 -04:00
/**
* creates a container holding all mocks necessary to create
* @return
*/
def createMocks: Mocks = {
val contextCreator: ContextCreator = mock[ContextCreator]
val context = mock[DirContext]
contextCreator.apply(anyString, anyString).returns(Right(context))
2018-07-27 10:18:29 -04:00
val searchResults = mock[NamingEnumeration[SearchResult]]
searchResults.hasMore.returns(true)
val mockAttribute = mock[Attribute]
mockAttribute.get().returns("")
val mockAttributes = mock[Attributes]
mockAttributes.get(anyString).returns(mockAttribute)
val searchNext = mock[SearchResult]
searchResults.next.returns(searchNext)
searchNext.getNameInNamespace.returns("")
searchNext.getAttributes.returns(mockAttributes)
context.search(anyString, anyString, any[SearchControls]).returns(searchResults)
val byDomainAuthenticator = new LdapByDomainAuthenticator(Settings, contextCreator)
Mocks(contextCreator, context, searchResults, searchNext, byDomainAuthenticator, mockAttributes)
}
val testDomain1 = LdapSearchDomain("someDomain", "DC=test,DC=test,DC=com")
val testDomain2 = LdapSearchDomain("anotherDomain", "DC=test,DC=com")
val nonexistentUser = User("does-not-exist", "accessKey", "secretKey")
2018-07-27 10:18:29 -04:00
"LdapAuthenticator" should {
"apply method must create an LDAP Authenticator" in {
val testConfig: Configuration =
Configuration.load(Environment.simple()) ++ Configuration.from(
Map("portal.test_login" -> false)
)
val underTest = LdapAuthenticator.apply(new Settings(testConfig))
underTest must beAnInstanceOf[LdapAuthenticator]
2018-07-27 10:18:29 -04:00
}
"apply method must create a Test Authenticator if selected" in {
val testConfig: Configuration =
Configuration.load(Environment.simple()) ++ Configuration.from(
Map("portal.test_login" -> true)
)
val underTest = LdapAuthenticator.apply(new Settings(testConfig))
2018-07-27 10:18:29 -04:00
underTest must beAnInstanceOf[TestAuthenticator]
}
".authenticate" should {
"authenticate first with 1st domain" in {
2018-07-27 10:18:29 -04:00
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
byDomainAuthenticator
.authenticate(testDomain1, "foo", "bar")
.returns(Right(LdapUserDetails("", "", None, None, None)))
2018-07-27 10:18:29 -04:00
val authenticator =
new LdapAuthenticator(List(testDomain1), byDomainAuthenticator, mock[ServiceAccount])
val response = authenticator.authenticate("foo", "bar")
there.was(one(byDomainAuthenticator).authenticate(testDomain1, "foo", "bar"))
there.was(no(byDomainAuthenticator).authenticate(testDomain2, "foo", "bar"))
"and return Right if authenticated" in {
response must beRight
2018-07-27 10:18:29 -04:00
}
}
"authenticate with 2nd domain if 1st fails with UserDoesNotExistException" in {
2018-07-27 10:18:29 -04:00
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
byDomainAuthenticator
.authenticate(testDomain1, "foo", "bar")
.returns(Left(UserDoesNotExistException("first failed")))
2018-07-27 10:18:29 -04:00
byDomainAuthenticator
.authenticate(testDomain2, "foo", "bar")
.returns(Right(LdapUserDetails("", "", None, None, None)))
2018-07-27 10:18:29 -04:00
val authenticator = new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
mock[ServiceAccount]
)
2018-07-27 10:18:29 -04:00
val response = authenticator.authenticate("foo", "bar")
there.was(one(byDomainAuthenticator).authenticate(testDomain1, "foo", "bar"))
there.was(one(byDomainAuthenticator).authenticate(testDomain2, "foo", "bar"))
"and return a Success if authenticated" in {
response must beRight
}
}
"return an error if all domains lookups fail but services are up" in {
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
byDomainAuthenticator
.authenticate(testDomain1, "foo", "bar")
.returns(Left(UserDoesNotExistException("first failed")))
byDomainAuthenticator
.authenticate(testDomain2, "foo", "bar")
.returns(Left(UserDoesNotExistException("second failed")))
val authenticator = new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
mock[ServiceAccount]
)
val response = authenticator.authenticate("foo", "bar")
there.was(one(byDomainAuthenticator).authenticate(testDomain1, "foo", "bar"))
there.was(one(byDomainAuthenticator).authenticate(testDomain2, "foo", "bar"))
"and return error message" in {
response must beLeft
2018-07-27 10:18:29 -04:00
}
}
"return an error if all domains fail with at least one LDAP connectivity issue" in {
2018-07-27 10:18:29 -04:00
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
byDomainAuthenticator
.authenticate(testDomain1, "foo", "bar")
.returns(Left(UserDoesNotExistException("first failed")))
2018-07-27 10:18:29 -04:00
byDomainAuthenticator
.authenticate(testDomain2, "foo", "bar")
.returns(Left(LdapServiceException("some bad exception")))
2018-07-27 10:18:29 -04:00
val authenticator = new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
mock[ServiceAccount]
)
2018-07-27 10:18:29 -04:00
val response = authenticator.authenticate("foo", "bar")
there.was(one(byDomainAuthenticator).authenticate(testDomain1, "foo", "bar"))
there.was(one(byDomainAuthenticator).authenticate(testDomain2, "foo", "bar"))
"and return error message" in {
response must beLeft
2018-07-27 10:18:29 -04:00
}
}
"return an error if no LDAP search domains are provided" in {
val noDomainsLdapAuthenticator =
new LdapAuthenticator(List(), mock[LdapByDomainAuthenticator], mock[ServiceAccount])
noDomainsLdapAuthenticator.authenticate("someUserName", "somePassword") must beLeft
}
2018-07-27 10:18:29 -04:00
}
".lookup" should {
"lookup first with 1st domain" in {
2018-07-27 10:18:29 -04:00
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = ServiceAccount("first", "foo", "bar")
2018-07-27 10:18:29 -04:00
byDomainAuthenticator
.lookup(testDomain1, "foo", serviceAccount)
.returns(Right(LdapUserDetails("", "", None, None, None)))
2018-07-27 10:18:29 -04:00
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
2018-07-27 10:18:29 -04:00
val response = authenticator.lookup("foo")
there.was(one(byDomainAuthenticator).lookup(testDomain1, "foo", serviceAccount))
there.was(no(byDomainAuthenticator).authenticate(testDomain2, "foo", "bar"))
"and return details if authenticated" in {
response must beRight
2018-07-27 10:18:29 -04:00
}
"return an error if no LDAP search domains are provided" in {
val noDomainsLdapAuthenticator =
new LdapAuthenticator(List(), mock[LdapByDomainAuthenticator], mock[ServiceAccount])
noDomainsLdapAuthenticator.lookup("someUserName") must beLeft
}
2018-07-27 10:18:29 -04:00
}
"lookup with 2nd domain if 1st fails with UserDoesNotExistException" in {
2018-07-27 10:18:29 -04:00
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "foo", serviceAccount)
.returns(Left(UserDoesNotExistException("first failed")))
2018-07-27 10:18:29 -04:00
byDomainAuthenticator
.lookup(testDomain2, "foo", serviceAccount)
.returns(Right(LdapUserDetails("", "", None, None, None)))
2018-07-27 10:18:29 -04:00
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
2018-07-27 10:18:29 -04:00
val response = authenticator.lookup("foo")
there.was(one(byDomainAuthenticator).lookup(testDomain1, "foo", serviceAccount))
there.was(one(byDomainAuthenticator).lookup(testDomain2, "foo", serviceAccount))
"and return None if authenticated" in {
response must beRight
}
}
"return an error if all domains lookups fail but services are up" in {
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "foo", serviceAccount)
.returns(Left(UserDoesNotExistException("first failed")))
byDomainAuthenticator
.lookup(testDomain2, "foo", serviceAccount)
.returns(Left(UserDoesNotExistException("second failed")))
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
val response = authenticator.lookup("foo")
there.was(one(byDomainAuthenticator).lookup(testDomain1, "foo", serviceAccount))
there.was(one(byDomainAuthenticator).lookup(testDomain2, "foo", serviceAccount))
"and return error message" in {
response must beLeft
2018-07-27 10:18:29 -04:00
}
}
"return error if all lookups fail with at least one LDAP connectivity issue" in {
2018-07-27 10:18:29 -04:00
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "foo", serviceAccount)
.returns(Left(LdapServiceException("some LDAP connectivity issue")))
2018-07-27 10:18:29 -04:00
byDomainAuthenticator
.lookup(testDomain2, "foo", serviceAccount)
.returns(Left(UserDoesNotExistException("second failed")))
2018-07-27 10:18:29 -04:00
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
2018-07-27 10:18:29 -04:00
val response = authenticator.lookup("foo")
there.was(one(byDomainAuthenticator).lookup(testDomain1, "foo", serviceAccount))
there.was(one(byDomainAuthenticator).lookup(testDomain2, "foo", serviceAccount))
"and return error message" in {
response must beLeft
2018-07-27 10:18:29 -04:00
}
}
}
".healthCheck" should {
"fail if there is some unexpected error" in {
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "healthlookup", serviceAccount)
.returns(Left(LdapServiceException("some failure")))
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
authenticator.healthCheck()
val response = authenticator.healthCheck().unsafeRunSync()
response should beLeft[HealthCheckError]
}
"succeed if the dummy user cant be found" in {
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "healthlookup", serviceAccount)
.returns(Left(UserDoesNotExistException("does not exist")))
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
authenticator.healthCheck()
val response = authenticator.healthCheck().unsafeRunSync()
response should beRight[Unit]
}
"succeed if the dummy user can be found" in {
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "healthlookup", serviceAccount)
.returns(Right(LdapUserDetails("", "", None, None, None)))
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
authenticator.healthCheck()
val response = authenticator.healthCheck().unsafeRunSync()
response should beRight[Unit]
}
}
".getUsersNotInLdap" should {
"return a list of users not found in LDAP" in {
val byDomainAuthenticator = mock[LdapByDomainAuthenticator]
val serviceAccount = mock[ServiceAccount]
byDomainAuthenticator
.lookup(testDomain1, "does-not-exist", serviceAccount)
.returns(Left(UserDoesNotExistException("does not exist")))
byDomainAuthenticator
.lookup(testDomain2, "does-not-exist", serviceAccount)
.returns(Left(UserDoesNotExistException("does not exist")))
byDomainAuthenticator
.lookup(testDomain1, "existing-user", serviceAccount)
.returns(Right(LdapUserDetails("", "", None, None, None)))
byDomainAuthenticator
.lookup(testDomain1, "another-existing-user", serviceAccount)
.returns(Left(UserDoesNotExistException("does not exist")))
byDomainAuthenticator
.lookup(testDomain2, "another-existing-user", serviceAccount)
.returns(Right(LdapUserDetails("", "", None, None, None)))
byDomainAuthenticator
.lookup(testDomain1, serviceAccount.name, serviceAccount)
.returns(Right(LdapUserDetails("", "", None, None, None)))
val authenticator =
new LdapAuthenticator(
List(testDomain1, testDomain2),
byDomainAuthenticator,
serviceAccount
)
authenticator
.getUsersNotInLdap(
List(
nonexistentUser,
nonexistentUser.copy(userName = "existing-user"),
nonexistentUser.copy(userName = "another-existing-user")
)
)
.unsafeRunSync() must
beEqualTo(List(nonexistentUser))
}
}
2018-07-27 10:18:29 -04:00
}
"LdapByDomainAuthenticator" should {
"return an error message if authenticated but no LDAP record is found" in {
val mocks = createMocks
mocks.searchResults.hasMore.returns(false)
val response = mocks.byDomainAuthenticator.authenticate(testDomain1, "foo", "bar")
response must beLeft
2018-07-27 10:18:29 -04:00
}
"if creating context succeeds" in {
"and result.hasMore is true" in {
val mocks = createMocks
val response = mocks.byDomainAuthenticator.authenticate(testDomain1, "foo", "bar")
"return Success" in {
response must beRight
2018-07-27 10:18:29 -04:00
}
"call contextCreator.apply" in {
Support non ActiveDirectory LDAP (#859) Support non ActiveDirectory LDAP This PR has an optional local portal setup against this docker container - https://github.com/rroemhild/docker-test-openldap The base modifications for LDAP was to change the actual authentication flow. Before, we only attempted to bind (setting up a DirContext and relying on an exception). We would test all of the search bases until we exhausted the list. The new approach works differently: 1. First, login using the main service account 2. Second, do a lookup of the user 3. Finally, attempt to bind to that user's context directly using the password provided. This works fine with both AD LDAP as well as the example docker container which uses OpenLDAP Besides these changes, need to make configurable the userNameField, which is the ldap attribute that is used to search for the username sent in the login screen. In AD, this is `sAMAccountName`, but in the example it is `uid`, the logon field is up to the way LDAP is setup - `docker-up-vinyldns.sh` - fixed a quote issue with the startup script to properly send in the version of vinyldns - `docker-compose-build.yml` - added the `ldap` container so the portal can connect as `vinyldns-ldap` - `docker/portal/application.conf` - new config file so that we can connect to the new ldap container - `docker-compose.yml` - added the `ldap` container here as well so we can play with it using `reStart` in sbt instead of `docker-up-vinyldns.sh` - simplifies local testing - `LdapAuthenticator.scala` - this is where the main changes happen
2019-10-08 19:13:15 -04:00
// We first authenticate to the service account, and then to the user
there.was(
one(mocks.contextCreator).apply("test\\test", "test"),
one(mocks.contextCreator).apply("", "bar")
)
2018-07-27 10:18:29 -04:00
}
"call the correct search on context" in {
//because specs2 doesn't compare SearchControls objects properly, we have to use argument capture. And since
//mockito only allows all raw variable comparisons or mock variable comparisons, had to use argument
//capture on everything
val baseNameCapture = new ArgumentCapture[String]
val usernameFilterCapture = new ArgumentCapture[String]
val searchControlCapture = new ArgumentCapture[SearchControls]
there.was(
one(mocks.context).search(baseNameCapture, usernameFilterCapture, searchControlCapture)
)
2018-07-27 10:18:29 -04:00
searchControlCapture.value.getSearchScope mustEqual 2
baseNameCapture.value mustEqual "DC=test,DC=test,DC=com"
usernameFilterCapture.value mustEqual "(sAMAccountName=foo)"
}
"call result.hasMore" in {
there.was(one(mocks.searchResults).hasMore)
}
"call result.next" in {
there.was(one(mocks.searchResults).next())
}
"call result.next.getNameInNamespace" in {
there.was(one(mocks.searchNext).getNameInNamespace)
}
"call result.next.getAttributes" in {
there.was(one(mocks.searchNext).getAttributes)
}
"call attributes.get for username, email, firstname and lastname" in {
there.was(one(mocks.attributes).get("sAMAccountName"))
there.was(one(mocks.attributes).get("mail"))
there.was(one(mocks.attributes).get("givenName"))
there.was(one(mocks.attributes).get("sn"))
}
}
"and result.hasMore is false" in {
val mocks = createMocks
mocks.searchResults.hasMore.returns(false)
val response = mocks.byDomainAuthenticator.authenticate(testDomain1, "foo", "bar")
"return a UserDoesNotExistException" in {
response must beLeft[LdapException]
2018-07-27 10:18:29 -04:00
}
}
}
"if creating the context fails" in {
val mocks = createMocks
mocks.contextCreator
.apply(anyString, anyString)
.returns(Left(LdapServiceException("oops")))
2018-07-27 10:18:29 -04:00
val response = mocks.byDomainAuthenticator.authenticate(testDomain1, "foo", "bar")
"return an error" in {
response must beLeft
2018-07-27 10:18:29 -04:00
}
}
"lookup a user" should {
"return a user it can find" in {
val mocks = createMocks
val serviceAccount = ServiceAccount("second", "serviceuser", "servicepass")
2018-07-27 10:18:29 -04:00
val response = mocks.byDomainAuthenticator.lookup(testDomain1, "foo", serviceAccount)
response must beRight
2018-07-27 10:18:29 -04:00
"call contextCreator.apply" in {
there.was(one(mocks.contextCreator).apply("second\\serviceuser", "servicepass"))
2018-07-27 10:18:29 -04:00
}
"call the correct search on context" in {
//because specs2 doesn't compare SearchControls objects properly, we have to use argument capture. And since
//mockito only allows all raw variable comparisons or mock variable comparisons, had to use argument
//capture on everything
val baseNameCapture = new ArgumentCapture[String]
val usernameFilterCapture = new ArgumentCapture[String]
val searchControlCapture = new ArgumentCapture[SearchControls]
there.was(
one(mocks.context).search(baseNameCapture, usernameFilterCapture, searchControlCapture)
)
2018-07-27 10:18:29 -04:00
searchControlCapture.value.getSearchScope mustEqual 2
baseNameCapture.value mustEqual "DC=test,DC=test,DC=com"
usernameFilterCapture.value mustEqual "(sAMAccountName=foo)"
}
"call result.hasMore" in {
there.was(one(mocks.searchResults).hasMore)
}
"call result.next" in {
there.was(one(mocks.searchResults).next())
}
"call result.next.getNameInNamespace" in {
there.was(one(mocks.searchNext).getNameInNamespace)
}
"call result.next.getAttributes" in {
there.was(one(mocks.searchNext).getAttributes)
}
"call attributes.get for username, email, firstname and lastname" in {
there.was(one(mocks.attributes).get("sAMAccountName"))
there.was(one(mocks.attributes).get("mail"))
there.was(one(mocks.attributes).get("givenName"))
there.was(one(mocks.attributes).get("sn"))
}
}
"return a Failure if the user does not exist" in {
val mocks = createMocks
val serviceAccount = ServiceAccount("first", "foo", "bar")
2018-07-27 10:18:29 -04:00
mocks.searchResults.hasMore.returns(false)
val response = mocks.byDomainAuthenticator.lookup(testDomain1, "foo", serviceAccount)
response must beLeft
2018-07-27 10:18:29 -04:00
}
"return a Failure when the service user credentials are incorrect" in {
val mocks = createMocks
val serviceAccount = ServiceAccount("first", "foo", "bar")
2018-07-27 10:18:29 -04:00
mocks.contextCreator
.apply(anyString, anyString)
.returns(Left(LdapServiceException("oops")))
2018-07-27 10:18:29 -04:00
val response = mocks.byDomainAuthenticator.lookup(testDomain1, "foo", serviceAccount)
response must beLeft
2018-07-27 10:18:29 -04:00
}
}
}
"TestAuthenticator" should {
"authenticate the test user" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth
.authenticate(anyString, anyString)
.returns(Left(UserDoesNotExistException("should not be here")))
2018-07-27 10:18:29 -04:00
val underTest = new TestAuthenticator(mockLdapAuth)
val testUserLookup = underTest.authenticate("testuser", "testpassword")
2018-07-27 10:18:29 -04:00
testUserLookup must beRight(
LdapUserDetails(
2018-07-27 10:18:29 -04:00
"O=test,OU=testdata,CN=testuser",
"testuser",
Some("test@test.test"),
Some("Test"),
Some("User")
)
)
val recordPagingUserLookup = underTest.lookup("recordPagingTestUser")
recordPagingUserLookup must beRight(
LdapUserDetails(
"O=test,OU=testdata,CN=recordPagingTestUser",
"recordPagingTestUser",
Some("test@test.test"),
Some("Test"),
Some("User")
)
)
2018-07-27 10:18:29 -04:00
there.were(noCallsTo(mockLdapAuth))
}
"authenticate the record paging test user" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth
.authenticate(anyString, anyString)
.returns(Left(UserDoesNotExistException("should not be here")))
val underTest = new TestAuthenticator(mockLdapAuth)
val result = underTest.authenticate("recordPagingTestUser", "testpassword")
result must beRight(
LdapUserDetails(
"O=test,OU=testdata,CN=recordPagingTestUser",
"recordPagingTestUser",
Some("test@test.test"),
Some("Test"),
Some("User")
)
)
there.were(noCallsTo(mockLdapAuth))
}
2018-07-27 10:18:29 -04:00
"authenticate a user that is not the test user" in {
val mockLdapAuth = mock[LdapAuthenticator]
val userDetails =
LdapUserDetails("o=foo,cn=bar", "foo", Some("bar"), Some("baz"), Some("qux"))
mockLdapAuth.authenticate(anyString, anyString).returns(Right(userDetails))
2018-07-27 10:18:29 -04:00
val underTest = new TestAuthenticator(mockLdapAuth)
val result = underTest.authenticate("foo", "bar")
result must beRight(userDetails)
2018-07-27 10:18:29 -04:00
there.was(one(mockLdapAuth).authenticate("foo", "bar"))
}
"lookup the test user" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth
.authenticate(anyString, anyString)
.returns(Left(UserDoesNotExistException("should not be here")))
2018-07-27 10:18:29 -04:00
val underTest = new TestAuthenticator(mockLdapAuth)
val testUserLookup = underTest.lookup("testuser")
2018-07-27 10:18:29 -04:00
testUserLookup must beRight(
LdapUserDetails(
2018-07-27 10:18:29 -04:00
"O=test,OU=testdata,CN=testuser",
"testuser",
Some("test@test.test"),
Some("Test"),
Some("User")
)
)
val recordPagingUserLookup = underTest.lookup("recordPagingTestUser")
recordPagingUserLookup must beRight(
LdapUserDetails(
"O=test,OU=testdata,CN=recordPagingTestUser",
"recordPagingTestUser",
Some("test@test.test"),
Some("Test"),
Some("User")
)
)
2018-07-27 10:18:29 -04:00
there.were(noCallsTo(mockLdapAuth))
}
"lookup the record paging test user" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth
.authenticate(anyString, anyString)
.returns(Left(UserDoesNotExistException("should not be here")))
val underTest = new TestAuthenticator(mockLdapAuth)
val result = underTest.lookup("recordPagingTestUser")
result must beRight(
LdapUserDetails(
"O=test,OU=testdata,CN=recordPagingTestUser",
"recordPagingTestUser",
Some("test@test.test"),
Some("Test"),
Some("User")
)
)
there.were(noCallsTo(mockLdapAuth))
}
2018-07-27 10:18:29 -04:00
"lookup a user that is not the test user" in {
val mockLdapAuth = mock[LdapAuthenticator]
val userDetails =
LdapUserDetails("o=foo,cn=bar", "foo", Some("bar"), Some("baz"), Some("qux"))
mockLdapAuth.lookup(anyString).returns(Right(userDetails))
2018-07-27 10:18:29 -04:00
val underTest = new TestAuthenticator(mockLdapAuth)
val result = underTest.lookup("foo")
result must beRight(userDetails)
2018-07-27 10:18:29 -04:00
there.was(one(mockLdapAuth).lookup("foo"))
}
"find non-existent users" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth
.getUsersNotInLdap(List(nonexistentUser))
.returns(IO(List(nonexistentUser)))
val underTest = new TestAuthenticator(mockLdapAuth)
underTest.getUsersNotInLdap(List(nonexistentUser)).unsafeRunSync() must beEqualTo(
List(nonexistentUser)
)
}
"perform a health check" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth.healthCheck().returns(IO(Right(())))
val underTest = new TestAuthenticator(mockLdapAuth)
underTest.healthCheck().unsafeRunSync() must beRight(())
}
2018-07-27 10:18:29 -04:00
}
"return a successful health check" in {
val mockLdapAuth = mock[LdapAuthenticator]
mockLdapAuth.healthCheck().returns(IO(Right(())).asHealthCheck(classOf[LdapAuthenticatorSpec]))
new TestAuthenticator(mockLdapAuth).healthCheck().unsafeRunSync() should beRight[Unit]
}
2018-07-27 10:18:29 -04:00
}