Skip to content

Commit 9d8b42d

Browse files
committed
Modify ldap init to support multiple ldap hosts
1 parent 9a65030 commit 9d8b42d

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ sudo dnf install python2-devel python3-devel openldap-devel
2424
| base_ou | yes | | Base OU to search for user and group entries |
2525
| group_dns | yes | | Which groups user must be member of to be granted access (group names are considered case-insensitive) |
2626
| group_dns_check | no | `and` | What kind of check to perform when validating user group membership (`and` / `or`). When `and` behavior is used, user needs to be part of all the specified groups and when `or` behavior is used, user needs to be part of at least one or more of the specified groups. |
27-
| host | yes | | Hostname of the LDAP server |
27+
| host | yes | | Hostname of the LDAP server. Multiple comma-separated entries are allowed. |
2828
| port | yes | | Port of the LDAP server |
2929
| use_ssl | no | `false` | Use LDAPS to connect |
3030
| use_tls | no | `false` | Start TLS on LDAP to connect |

st2auth_ldap/ldap_backend.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,11 @@ def _init_connection(self):
279279

280280
# Setup connection and options.
281281
protocol = 'ldaps' if self._use_ssl else 'ldap'
282-
endpoint = '%s://%s:%d' % (protocol, self._host, int(self._port))
282+
hosts = self._host.split(',')
283+
for i in range(len(hosts)):
284+
hosts[i] = '%s://%s:%d' % (protocol, hosts[i], int(self._port))
285+
286+
endpoint = ','.join(hosts)
283287
connection = ldap.initialize(endpoint, trace_level=trace_level)
284288
connection.set_option(ldap.OPT_DEBUG_LEVEL, 255)
285289
connection.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)

tests/unit/test_backend.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626

2727
LDAP_HOST = '127.0.0.1'
28+
LDAP_MULTIPLE_HOSTS = '127.0.0.1,localhost'
2829
LDAPS_PORT = 636
2930
LDAP_BIND_DN = 'cn=Administrator,cn=users,dc=stackstorm,dc=net'
3031
LDAP_BIND_PASSWORD = uuid.uuid4().hex
@@ -114,6 +115,25 @@ def test_authenticate(self):
114115
authenticated = backend.authenticate(LDAP_USER_UID, LDAP_USER_PASSWD)
115116
self.assertTrue(authenticated)
116117

118+
@mock.patch.object(
119+
ldap.ldapobject.SimpleLDAPObject, 'simple_bind_s',
120+
mock.MagicMock(return_value=None))
121+
@mock.patch.object(
122+
ldap.ldapobject.SimpleLDAPObject, 'search_s',
123+
mock.MagicMock(side_effect=[LDAP_USER_SEARCH_RESULT, LDAP_GROUP_SEARCH_RESULT]))
124+
def test_authenticate_with_multiple_ldap_hosts(self):
125+
backend = ldap_backend.LDAPAuthenticationBackend(
126+
LDAP_BIND_DN,
127+
LDAP_BIND_PASSWORD,
128+
LDAP_BASE_OU,
129+
LDAP_GROUP_DNS,
130+
LDAP_MULTIPLE_HOSTS,
131+
id_attr=LDAP_ID_ATTR
132+
)
133+
134+
authenticated = backend.authenticate(LDAP_USER_UID, LDAP_USER_PASSWD)
135+
self.assertTrue(authenticated)
136+
117137
@mock.patch.object(
118138
ldap.ldapobject.SimpleLDAPObject, 'simple_bind_s',
119139
mock.MagicMock(return_value=None))

0 commit comments

Comments
 (0)