Updating requirements and adding restart tests for LDAP external user directory test suite.

This commit is contained in:
Vitaliy Zakaznikov 2020-10-12 19:54:07 -04:00
parent 23460ddaab
commit f34274dc08
7 changed files with 571 additions and 174 deletions

View File

@ -47,6 +47,37 @@ ASCII_CHARS = string.ascii_lowercase + string.ascii_uppercase + string.digits
def randomword(length, chars=ASCII_CHARS):
return ''.join(random.choice(chars) for i in range(length))
def restart(node=None, safe=False, timeout=20):
"""Restart ClickHouse server and wait for config to be reloaded.
"""
with When("I restart ClickHouse server node"):
if node is None:
node = current().context.node
with node.cluster.shell(node.name) as bash:
bash.expect(bash.prompt)
with By("closing terminal to the node to be restarted"):
bash.close()
with And("getting current log size"):
logsize = \
node.command("ls -s --block-size=1 /var/log/clickhouse-server/clickhouse-server.log").output.split(" ")[
0].strip()
with And("restarting ClickHouse server"):
node.restart(safe=safe)
with Then("tailing the log file from using previous log size as the offset"):
bash.prompt = bash.__class__.prompt
bash.open()
bash.send(f"tail -c +{logsize} -f /var/log/clickhouse-server/clickhouse-server.log")
with And("waiting for config reload message in the log file"):
bash.expect(
f"ConfigReloader: Loaded config '/etc/clickhouse-server/config.xml', performed update on configuration",
timeout=timeout)
def add_config(config, timeout=20, restart=False):
"""Add dynamic configuration file to ClickHouse.

View File

@ -45,6 +45,7 @@ def regression(self, local, clickhouse_binary_path):
Scenario(run=load("ldap.authentication.tests.sanity", "scenario"))
Scenario(run=load("ldap.external_user_directory.tests.simple", "scenario"))
Feature(run=load("ldap.external_user_directory.tests.restart", "feature"))
Feature(run=load("ldap.external_user_directory.tests.server_config", "feature"))
Feature(run=load("ldap.external_user_directory.tests.external_user_directory_config", "feature"))
Feature(run=load("ldap.external_user_directory.tests.connections", "feature"))

View File

@ -27,6 +27,7 @@
* 4.1.1.15 [RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.LocalOnly](#rqsrs-009ldapexternaluserdirectoryauthenticationparallellocalonly)
* 4.1.1.16 [RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.LocalAndMultipleLDAP](#rqsrs-009ldapexternaluserdirectoryauthenticationparallellocalandmultipleldap)
* 4.1.1.17 [RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.SameUser](#rqsrs-009ldapexternaluserdirectoryauthenticationparallelsameuser)
* 4.1.1.18 [RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.DynamicallyAddedAndRemovedUsers](#rqsrs-009ldapexternaluserdirectoryauthenticationparalleldynamicallyaddedandremovedusers)
* 4.1.2 [Connection](#connection)
* 4.1.2.1 [RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.PlainText](#rqsrs-009ldapexternaluserdirectoryconnectionprotocolplaintext)
* 4.1.2.2 [RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.TLS](#rqsrs-009ldapexternaluserdirectoryconnectionprotocoltls)
@ -41,6 +42,8 @@
* 4.2 [Specific](#specific)
* 4.2.1 [User Discovery](#user-discovery)
* 4.2.1.1 [RQ.SRS-009.LDAP.ExternalUserDirectory.Users.Lookup.Priority](#rqsrs-009ldapexternaluserdirectoryuserslookuppriority)
* 4.2.1.2 [RQ.SRS-009.LDAP.ExternalUserDirectory.Restart.Server](#rqsrs-009ldapexternaluserdirectoryrestartserver)
* 4.2.1.3 [RQ.SRS-009.LDAP.ExternalUserDirectory.Restart.Server.ParallelLogins](#rqsrs-009ldapexternaluserdirectoryrestartserverparallellogins)
* 4.2.2 [Roles](#roles)
* 4.2.2.1 [RQ.SRS-009.LDAP.ExternalUserDirectory.Role.Removed](#rqsrs-009ldapexternaluserdirectoryroleremoved)
* 4.2.2.2 [RQ.SRS-009.LDAP.ExternalUserDirectory.Role.Removed.Privileges](#rqsrs-009ldapexternaluserdirectoryroleremovedprivileges)
@ -236,6 +239,13 @@ version: 1.0
[ClickHouse] SHALL support parallel authentication of the same external [LDAP] user
authenticated using the same [LDAP] external user directory.
##### RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.DynamicallyAddedAndRemovedUsers
version: 1.0
[ClickHouse] SHALL support parallel authentication of users using
[LDAP] external user directory when [LDAP] users are dynamically added and
removed.
#### Connection
##### RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.PlainText
@ -309,6 +319,18 @@ version: 2.0
[ClickHouse] SHALL lookup user presence in the same order
as user directories are defined in the `config.xml`.
##### RQ.SRS-009.LDAP.ExternalUserDirectory.Restart.Server
version: 1.0
[ClickHouse] SHALL support restarting server when one or more LDAP external directories
are configured.
##### RQ.SRS-009.LDAP.ExternalUserDirectory.Restart.Server.ParallelLogins
version: 1.0
[ClickHouse] SHALL support restarting server when one or more LDAP external directories
are configured during parallel [LDAP] user logins.
#### Roles
##### RQ.SRS-009.LDAP.ExternalUserDirectory.Role.Removed

View File

@ -1,6 +1,6 @@
# These requirements were auto generated
# from software requirements specification (SRS)
# document by TestFlows v1.6.200929.1033606.
# document by TestFlows v1.6.201009.1190249.
# Do not edit by hand but re-generate instead
# using 'tfs requirements generate' command.
from testflows.core import Requirement
@ -14,9 +14,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication = Requirement(
uid=None,
description=(
'[ClickHouse] SHALL support authenticating users that are defined only on the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_MultipleUserDirectories = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.MultipleUserDirectories',
@ -27,9 +27,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_MultipleUserDirectories = Requirement(
uid=None,
description=(
'[ClickHouse] SHALL support authenticating users using multiple [LDAP] external user directories.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_MultipleUserDirectories_Lookup = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.MultipleUserDirectories.Lookup',
@ -44,9 +44,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_MultipleUserDirectories_Lookup = Requireme
'in which user directories are specified in the `config.xml` file.\n'
'If a user cannot be authenticated using the first [LDAP] external user directory\n'
'then the next user directory in the list SHALL be used.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Users_Authentication_NewUsers = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Users.Authentication.NewUsers',
@ -58,9 +58,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Users_Authentication_NewUsers = Requiremen
description=(
'[ClickHouse] SHALL support authenticating users that are defined only on the [LDAP] server\n'
'as soon as they are added to the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_DeletedUsers = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.DeletedUsers',
@ -73,9 +73,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_DeletedUsers = Requirement(
'[ClickHouse] SHALL not allow authentication of users that\n'
'were previously defined only on the [LDAP] server but were removed\n'
'from the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Valid = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Valid',
@ -88,9 +88,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Valid = Requirement(
'[ClickHouse] SHALL only allow user authentication using [LDAP] server if and only if\n'
'user name and password match [LDAP] server records for the user\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Invalid = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Invalid',
@ -103,9 +103,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Invalid = Requirement(
'[ClickHouse] SHALL return an error and prohibit authentication if either user name or password\n'
'do not match [LDAP] server records for the user\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_UsernameChanged = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.UsernameChanged',
@ -117,9 +117,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_UsernameChanged = Requireme
description=(
'[ClickHouse] SHALL return an error and prohibit authentication if the username is changed\n'
'on the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_PasswordChanged = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.PasswordChanged',
@ -131,9 +131,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_PasswordChanged = Requireme
description=(
'[ClickHouse] SHALL return an error and prohibit authentication if the password\n'
'for the user is changed on the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_LDAPServerRestart = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.LDAPServerRestart',
@ -145,9 +145,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_LDAPServerRestart = Require
description=(
'[ClickHouse] SHALL support authenticating users after [LDAP] server is restarted\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_ClickHouseServerRestart = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.ClickHouseServerRestart',
@ -159,9 +159,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_ClickHouseServerRestart = R
description=(
'[ClickHouse] SHALL support authenticating users after server is restarted\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel',
@ -173,9 +173,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel = Requirement(
description=(
'[ClickHouse] SHALL support parallel authentication of users using [LDAP] server\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_ValidAndInvalid = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.ValidAndInvalid',
@ -189,9 +189,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_ValidAndInvalid =
'prohibit authentication of invalid users using [LDAP] server\n'
'in parallel without having invalid attempts affecting valid authentications\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_MultipleServers = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.MultipleServers',
@ -203,9 +203,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_MultipleServers =
description=(
'[ClickHouse] SHALL support parallel authentication of external [LDAP] users\n'
'authenticated using multiple [LDAP] external user directories.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_LocalOnly = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.LocalOnly',
@ -217,9 +217,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_LocalOnly = Requir
description=(
'[ClickHouse] SHALL support parallel authentication of users defined only locally\n'
'when one or more [LDAP] external user directories are specified in the configuration file.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_LocalAndMultipleLDAP = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.LocalAndMultipleLDAP',
@ -231,9 +231,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_LocalAndMultipleLD
description=(
'[ClickHouse] SHALL support parallel authentication of local and external [LDAP] users\n'
'authenticated using multiple [LDAP] external user directories.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_SameUser = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.SameUser',
@ -245,9 +245,24 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_SameUser = Require
description=(
'[ClickHouse] SHALL support parallel authentication of the same external [LDAP] user\n'
'authenticated using the same [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Parallel_DynamicallyAddedAndRemovedUsers = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Parallel.DynamicallyAddedAndRemovedUsers',
version='1.0',
priority=None,
group=None,
type=None,
uid=None,
description=(
'[ClickHouse] SHALL support parallel authentication of users using\n'
'[LDAP] external user directory when [LDAP] users are dynamically added and\n'
'removed.\n'
'\n'
),
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_PlainText = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.PlainText',
@ -259,9 +274,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_PlainText = Requiremen
description=(
'[ClickHouse] SHALL support user authentication using plain text `ldap://` non secure protocol\n'
'while connecting to the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.TLS',
@ -273,9 +288,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS = Requirement(
description=(
'[ClickHouse] SHALL support user authentication using `SSL/TLS` `ldaps://` secure protocol\n'
'while connecting to the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_StartTLS = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.StartTLS',
@ -288,9 +303,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_StartTLS = Requirement
'[ClickHouse] SHALL support user authentication using legacy `StartTLS` protocol which is a\n'
'plain text `ldap://` protocol that is upgraded to [TLS] when connecting to the [LDAP] server\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS_Certificate_Validation = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.TLS.Certificate.Validation',
@ -302,9 +317,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS_Certificate_Valida
description=(
'[ClickHouse] SHALL support certificate validation used for [TLS] connections\n'
'to the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS_Certificate_SelfSigned = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.TLS.Certificate.SelfSigned',
@ -316,9 +331,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS_Certificate_SelfSi
description=(
'[ClickHouse] SHALL support self-signed certificates for [TLS] connections\n'
'to the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS_Certificate_SpecificCertificationAuthority = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Protocol.TLS.Certificate.SpecificCertificationAuthority',
@ -330,9 +345,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Protocol_TLS_Certificate_Specif
description=(
'[ClickHouse] SHALL support certificates signed by specific Certification Authority for [TLS] connections\n'
'to the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_Mechanism_Anonymous = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Authentication.Mechanism.Anonymous',
@ -344,9 +359,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_Mechanism_Anonym
description=(
'[ClickHouse] SHALL return an error and prohibit authentication using [Anonymous Authentication Mechanism of Simple Bind]\n'
'authentication mechanism when connecting to the [LDAP] server when using [LDAP] external server directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_Mechanism_Unauthenticated = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Authentication.Mechanism.Unauthenticated',
@ -358,9 +373,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_Mechanism_Unauth
description=(
'[ClickHouse] SHALL return an error and prohibit authentication using [Unauthenticated Authentication Mechanism of Simple Bind]\n'
'authentication mechanism when connecting to the [LDAP] server when using [LDAP] external server directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_Mechanism_NamePassword = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Authentication.Mechanism.NamePassword',
@ -372,9 +387,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_Mechanism_NamePa
description=(
'[ClickHouse] SHALL allow authentication using only [Name/Password Authentication Mechanism of Simple Bind]\n'
'authentication mechanism when connecting to the [LDAP] server when using [LDAP] external server directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_UnreachableServer = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Connection.Authentication.UnreachableServer',
@ -386,9 +401,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Connection_Authentication_UnreachableServe
description=(
'[ClickHouse] SHALL return an error and prohibit user login if [LDAP] server is unreachable\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Users_Lookup_Priority = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Users.Lookup.Priority',
@ -400,9 +415,37 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Users_Lookup_Priority = Requirement(
description=(
'[ClickHouse] SHALL lookup user presence in the same order\n'
'as user directories are defined in the `config.xml`.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Restart_Server = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Restart.Server',
version='1.0',
priority=None,
group=None,
type=None,
uid=None,
description=(
'[ClickHouse] SHALL support restarting server when one or more LDAP external directories\n'
'are configured.\n'
'\n'
),
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Restart_Server_ParallelLogins = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Restart.Server.ParallelLogins',
version='1.0',
priority=None,
group=None,
type=None,
uid=None,
description=(
'[ClickHouse] SHALL support restarting server when one or more LDAP external directories\n'
'are configured during parallel [LDAP] user logins.\n'
'\n'
),
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Role_Removed = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Role.Removed',
@ -416,9 +459,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Role_Removed = Requirement(
'of the external user directory are not defined at the time of the authentication attempt\n'
'with an exception that if a user was able to authenticate in past and its internal user object was created and cached\n'
'then the user SHALL be able to authenticate again, even if one of the roles is missing.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Role_Removed_Privileges = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Role.Removed.Privileges',
@ -432,9 +475,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Role_Removed_Privileges = Requirement(
'users authenticated using external user directory if it is removed\n'
'including currently cached users that are still able to authenticated where the removed\n'
'role is specified in the configuration of the external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Role_Readded_Privileges = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Role.Readded.Privileges',
@ -447,9 +490,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Role_Readded_Privileges = Requirement(
'[ClickHouse] SHALL reassign the role and add the privileges provided by the role\n'
'when it is re-added after removal for all LDAP users authenticated using external user directory\n'
'including any cached users where the re-added role was specified in the configuration of the external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Role_New = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Role.New',
@ -462,9 +505,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Role_New = Requirement(
'[ClickHouse] SHALL not allow any new roles to be assigned to any LDAP\n'
'users authenticated using external user directory unless the role is specified\n'
'in the configuration of the external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Role_NewPrivilege = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Role.NewPrivilege',
@ -477,9 +520,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Role_NewPrivilege = Requirement(
'[ClickHouse] SHALL add new privilege to all the LDAP users authenticated using external user directory\n'
'including cached users when new privilege is added to one of the roles specified\n'
'in the configuration of the external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Role_RemovedPrivilege = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Role.RemovedPrivilege',
@ -492,9 +535,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Role_RemovedPrivilege = Requirement(
'[ClickHouse] SHALL remove privilege from all the LDAP users authenticated using external user directory\n'
'including cached users when privilege is removed from all the roles specified\n'
'in the configuration of the external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Invalid = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Invalid',
@ -505,9 +548,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Invalid = Requirement
uid=None,
description=(
'[ClickHouse] SHALL return an error and prohibit user login if [LDAP] server configuration is not valid.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Definition = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Definition',
@ -520,9 +563,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Definition = Requirem
'[ClickHouse] SHALL support using the [LDAP] servers defined in the\n'
'`ldap_servers` section of the `config.xml` as the server to be used\n'
'for a external user directory that uses an [LDAP] server as a source of user definitions.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Name = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Name',
@ -533,9 +576,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Name = Requirement(
uid=None,
description=(
'[ClickHouse] SHALL not support empty string as a server name.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Host = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Host',
@ -547,9 +590,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Host = Requirement(
description=(
'[ClickHouse] SHALL support `<host>` parameter to specify [LDAP]\n'
'server hostname or IP, this parameter SHALL be mandatory and SHALL not be empty.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Port = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Port',
@ -560,9 +603,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Port = Requirement(
uid=None,
description=(
'[ClickHouse] SHALL support `<port>` parameter to specify [LDAP] server port.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Port_Default = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Port.Default',
@ -573,9 +616,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Port_Default = Requir
uid=None,
description=(
'[ClickHouse] SHALL use default port number `636` if `enable_tls` is set to `yes` or `389` otherwise.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_AuthDN_Prefix = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.AuthDN.Prefix',
@ -587,9 +630,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_AuthDN_Prefix = Requi
description=(
'[ClickHouse] SHALL support `<auth_dn_prefix>` parameter to specify the prefix\n'
'of value used to construct the DN to bound to during authentication via [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_AuthDN_Suffix = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.AuthDN.Suffix',
@ -601,9 +644,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_AuthDN_Suffix = Requi
description=(
'[ClickHouse] SHALL support `<auth_dn_suffix>` parameter to specify the suffix\n'
'of value used to construct the DN to bound to during authentication via [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_AuthDN_Value = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.AuthDN.Value',
@ -616,9 +659,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_AuthDN_Value = Requir
'[ClickHouse] SHALL construct DN as `auth_dn_prefix + escape(user_name) + auth_dn_suffix` string.\n'
'\n'
"> This implies that auth_dn_suffix should usually have comma ',' as its first non-space character.\n"
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.EnableTLS',
@ -629,9 +672,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS = Requireme
uid=None,
description=(
'[ClickHouse] SHALL support `<enable_tls>` parameter to trigger the use of secure connection to the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_Default = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.EnableTLS.Options.Default',
@ -643,9 +686,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_Def
description=(
'[ClickHouse] SHALL use `yes` value as the default for `<enable_tls>` parameter\n'
'to enable SSL/TLS `ldaps://` protocol.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_No = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.EnableTLS.Options.No',
@ -657,9 +700,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_No
description=(
'[ClickHouse] SHALL support specifying `no` as the value of `<enable_tls>` parameter to enable\n'
'plain text `ldap://` protocol.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_Yes = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.EnableTLS.Options.Yes',
@ -671,9 +714,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_Yes
description=(
'[ClickHouse] SHALL support specifying `yes` as the value of `<enable_tls>` parameter to enable\n'
'SSL/TLS `ldaps://` protocol.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_StartTLS = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.EnableTLS.Options.StartTLS',
@ -685,9 +728,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_EnableTLS_Options_Sta
description=(
'[ClickHouse] SHALL support specifying `starttls` as the value of `<enable_tls>` parameter to enable\n'
'legacy `StartTLS` protocol that used plain text `ldap://` protocol, upgraded to [TLS].\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSMinimumProtocolVersion = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSMinimumProtocolVersion',
@ -699,9 +742,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSMinimumProtocolVer
description=(
'[ClickHouse] SHALL support `<tls_minimum_protocol_version>` parameter to specify\n'
'the minimum protocol version of SSL/TLS.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSMinimumProtocolVersion_Values = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSMinimumProtocolVersion.Values',
@ -713,9 +756,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSMinimumProtocolVer
description=(
'[ClickHouse] SHALL support specifying `ssl2`, `ssl3`, `tls1.0`, `tls1.1`, and `tls1.2`\n'
'as a value of the `<tls_minimum_protocol_version>` parameter.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSMinimumProtocolVersion_Default = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSMinimumProtocolVersion.Default',
@ -726,9 +769,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSMinimumProtocolVer
uid=None,
description=(
'[ClickHouse] SHALL set `tls1.2` as the default value of the `<tls_minimum_protocol_version>` parameter.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSRequireCert',
@ -740,9 +783,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert = Requ
description=(
'[ClickHouse] SHALL support `<tls_require_cert>` parameter to specify [TLS] peer\n'
'certificate verification behavior.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Options_Default = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSRequireCert.Options.Default',
@ -753,9 +796,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Option
uid=None,
description=(
'[ClickHouse] SHALL use `demand` value as the default for the `<tls_require_cert>` parameter.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Options_Demand = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSRequireCert.Options.Demand',
@ -768,9 +811,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Option
'[ClickHouse] SHALL support specifying `demand` as the value of `<tls_require_cert>` parameter to\n'
'enable requesting of client certificate. If no certificate is provided, or a bad certificate is\n'
'provided, the session SHALL be immediately terminated.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Options_Allow = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSRequireCert.Options.Allow',
@ -784,9 +827,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Option
'enable requesting of client certificate. If no\n'
'certificate is provided, the session SHALL proceed normally.\n'
'If a bad certificate is provided, it SHALL be ignored and the session SHALL proceed normally.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Options_Try = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSRequireCert.Options.Try',
@ -800,9 +843,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Option
'enable requesting of client certificate. If no certificate is provided, the session\n'
'SHALL proceed normally. If a bad certificate is provided, the session SHALL be\n'
'immediately terminated.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Options_Never = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSRequireCert.Options.Never',
@ -814,9 +857,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSRequireCert_Option
description=(
'[ClickHouse] SHALL support specifying `never` as the value of `<tls_require_cert>` parameter to\n'
'disable requesting of client certificate.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCertFile = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSCertFile',
@ -828,9 +871,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCertFile = Require
description=(
'[ClickHouse] SHALL support `<tls_cert_file>` to specify the path to certificate file used by\n'
'[ClickHouse] to establish connection with the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSKeyFile = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSKeyFile',
@ -842,9 +885,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSKeyFile = Requirem
description=(
'[ClickHouse] SHALL support `<tls_key_file>` to specify the path to key file for the certificate\n'
'specified by the `<tls_cert_file>` parameter.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCACertDir = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSCACertDir',
@ -856,9 +899,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCACertDir = Requir
description=(
'[ClickHouse] SHALL support `<tls_ca_cert_dir>` parameter to specify to a path to\n'
'the directory containing [CA] certificates used to verify certificates provided by the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCACertFile = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSCACertFile',
@ -870,9 +913,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCACertFile = Requi
description=(
'[ClickHouse] SHALL support `<tls_ca_cert_file>` parameter to specify a path to a specific\n'
'[CA] certificate file used to verify certificates provided by the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCipherSuite = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.TLSCipherSuite',
@ -893,9 +936,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_TLSCipherSuite = Requ
'\n'
'The available suites SHALL depend on the [OpenSSL] library version and variant used to build\n'
'[ClickHouse] and therefore might change.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Syntax = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Server.Syntax',
@ -926,9 +969,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Server_Syntax = Requirement(
' </my_ldap_server>\n'
'</yandex>\n'
'```\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_LDAPUserDirectory = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.LDAPUserDirectory',
@ -940,9 +983,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_LDAPUserDirectory = Re
description=(
'[ClickHouse] SHALL support `<ldap>` sub-section in the `<user_directories>` section of the `config.xml`\n'
'that SHALL define a external user directory that uses an [LDAP] server as a source of user definitions.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_LDAPUserDirectory_MoreThanOne = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.LDAPUserDirectory.MoreThanOne',
@ -955,9 +998,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_LDAPUserDirectory_More
'[ClickHouse] SHALL support more than one `<ldap>` sub-sections in the `<user_directories>` section of the `config.xml`\n'
'that SHALL allow to define more than one external user directory that use an [LDAP] server as a source\n'
'of user definitions.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Syntax = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Syntax',
@ -982,9 +1025,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Syntax = Requirement(
' </user_directories>\n'
'</yandex>\n'
'```\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Server',
@ -997,9 +1040,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server = Re
'[ClickHouse] SHALL support `server` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'section of the `config.xml` that SHALL specify one of LDAP server names\n'
'defined in `<ldap_servers>` section.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_Empty = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Server.Empty',
@ -1011,9 +1054,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_Empt
description=(
'[ClickHouse] SHALL return an error if the `server` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'is empty.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_Missing = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Server.Missing',
@ -1025,9 +1068,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_Miss
description=(
'[ClickHouse] SHALL return an error if the `server` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'is missing.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_MoreThanOne = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Server.MoreThanOne',
@ -1039,9 +1082,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_More
description=(
'[ClickHouse] SHALL only use the first definitition of the `server` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'if more than one `server` parameter is defined in the configuration.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_Invalid = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Server.Invalid',
@ -1053,9 +1096,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Server_Inva
description=(
'[ClickHouse] SHALL return an error if the server specified as the value of the `<server>`\n'
'parameter is not defined.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Roles',
@ -1068,9 +1111,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles = Req
'[ClickHouse] SHALL support `roles` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'section of the `config.xml` that SHALL specify the names of a locally defined roles that SHALL\n'
'be assigned to all users retrieved from the [LDAP] server.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_MoreThanOne = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Roles.MoreThanOne',
@ -1083,9 +1126,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_MoreT
'[ClickHouse] SHALL only use the first definitition of the `roles` parameter\n'
'in the `<ldap>` sub-section in the `<user_directories>`\n'
'if more than one `roles` parameter is defined in the configuration.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_Invalid = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Roles.Invalid',
@ -1097,9 +1140,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_Inval
description=(
'[ClickHouse] SHALL return an error if the role specified in the `<roles>`\n'
'parameter does not exist locally.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_Empty = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Roles.Empty',
@ -1112,9 +1155,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_Empty
'[ClickHouse] SHALL not allow users authenticated using LDAP external user directory\n'
'to perform any action if the `roles` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'section is empty.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_Missing = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Configuration.Users.Parameters.Roles.Missing',
@ -1127,9 +1170,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Configuration_Users_Parameters_Roles_Missi
'[ClickHouse] SHALL not allow users authenticated using LDAP external user directory\n'
'to perform any action if the `roles` parameter in the `<ldap>` sub-section in the `<user_directories>`\n'
'section is missing.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Username_Empty = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Username.Empty',
@ -1141,9 +1184,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Username_Empty = Requiremen
description=(
'[ClickHouse] SHALL not support authenticating users with empty username\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Username_Long = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Username.Long',
@ -1155,9 +1198,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Username_Long = Requirement
description=(
'[ClickHouse] SHALL support authenticating users with a long username of at least 256 bytes\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Username_UTF8 = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Username.UTF8',
@ -1169,9 +1212,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Username_UTF8 = Requirement
description=(
'[ClickHouse] SHALL support authentication users with a username that contains [UTF-8] characters\n'
'when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Password_Empty = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Password.Empty',
@ -1184,9 +1227,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Password_Empty = Requiremen
'[ClickHouse] SHALL not support authenticating users with empty passwords\n'
'even if an empty password is valid for the user and\n'
'is allowed by the [LDAP] server when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Password_Long = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Password.Long',
@ -1198,9 +1241,9 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Password_Long = Requirement
description=(
'[ClickHouse] SHALL support long password of at least 256 bytes\n'
'that can be used to authenticate users when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)
RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Password_UTF8 = Requirement(
name='RQ.SRS-009.LDAP.ExternalUserDirectory.Authentication.Password.UTF8',
@ -1212,6 +1255,6 @@ RQ_SRS_009_LDAP_ExternalUserDirectory_Authentication_Password_UTF8 = Requirement
description=(
'[ClickHouse] SHALL support [UTF-8] characters in passwords\n'
'used to authenticate users when using [LDAP] external user directory.\n'
'\n'
),
link=None
)
link=None)

View File

@ -26,14 +26,6 @@ servers = {
}
}
@TestStep(When)
@Name("I login as {username} and execute query")
def login_and_execute_query(self, username, password, exitcode=None, message=None, steps=True):
self.context.node.query("SELECT 1",
settings=[("user", username), ("password", password)],
exitcode=exitcode or 0,
message=message, steps=steps)
@TestOutline
def add_user_to_ldap_and_login(self, server, user=None, ch_user=None, login=None, exitcode=None, message=None):
"""Add user to LDAP and ClickHouse and then try to login."""

View File

@ -5,7 +5,7 @@ from contextlib import contextmanager
import testflows.settings as settings
from testflows.core import *
from testflows.asserts import error
from ldap.authentication.tests.common import getuid, Config, ldap_servers, add_config
from ldap.authentication.tests.common import getuid, Config, ldap_servers, add_config, restart
from ldap.authentication.tests.common import xmltree, xml_indent, xml_append, xml_with_utf8
from ldap.authentication.tests.common import ldap_user, ldap_users, add_user_to_ldap, delete_user_from_ldap
from ldap.authentication.tests.common import change_user_password_in_ldap, change_user_cn_in_ldap
@ -194,3 +194,11 @@ def login(servers, directory_server, *users, config=None):
settings=[("user", user["username"]), ("password", user["password"])],
exitcode=user.get("exitcode", None),
message=user.get("message", None))
@TestStep(When)
@Name("I login as {username} and execute query")
def login_and_execute_query(self, username, password, exitcode=None, message=None, steps=True, timeout=60):
self.context.node.query("SELECT 1",
settings=[("user", username), ("password", password)],
exitcode=exitcode or 0,
message=message, steps=steps, timeout=timeout)

View File

@ -0,0 +1,300 @@
import random
from multiprocessing.dummy import Pool
from testflows.core import *
from testflows.asserts import error
from ldap.external_user_directory.tests.common import *
from ldap.external_user_directory.requirements import *
@TestScenario
def one_external_user_directory(self, node="clickhouse1"):
"""Check that we can restart ClickHouse server when one
LDAP external user directory is configured.
"""
self.context.node = self.context.cluster.node(node)
servers = {
"openldap1": {
"host": "openldap1",
"port": "389",
"enable_tls": "no",
"auth_dn_prefix": "cn=",
"auth_dn_suffix": ",ou=users,dc=company,dc=com"
},
}
with ldap_servers(servers):
with rbac_roles("ldap_role") as roles:
with ldap_external_user_directory(server="openldap1", roles=roles, restart=True):
with Given("I login and execute query"):
login_and_execute_query(username="user1", password="user1")
with When("I then restart the server"):
restart()
with Then("I should be able to login and execute query after restart"):
login_and_execute_query(username="user1", password="user1")
@TestScenario
def multiple_external_user_directories(self, node="clickhouse1"):
"""Check that we can restart ClickHouse server when two
LDAP external user directory are configured.
"""
self.context.node = self.context.cluster.node(node)
servers = {
"openldap1": {
"host": "openldap1",
"port": "389",
"enable_tls": "no",
"auth_dn_prefix": "cn=",
"auth_dn_suffix": ",ou=users,dc=company,dc=com"
},
"openldap2": {
"host": "openldap2",
"port": "636",
"enable_tls": "yes",
"auth_dn_prefix": "cn=",
"auth_dn_suffix": ",ou=users,dc=company,dc=com",
"tls_require_cert": "never",
}
}
with Given("I have two LDAP servers"):
entries = [
(["openldap1"], []),
(["openldap2"], [])
]
with And("I create config file to define LDAP external user directory for each LDAP server"):
config = create_entries_ldap_external_user_directory_config_content(entries)
with ldap_servers(servers):
with ldap_external_user_directory(server=None, roles=None, restart=True, config=config):
with Given("I login and execute query using a user defined in the first LDAP server"):
login_and_execute_query(username="user1", password="user1")
with And("I login and execute query using a user defined the second LDAP server"):
login_and_execute_query(username="user2", password="user2")
with When("I restart the server"):
restart()
with Then("I should be able to login and execute query again using a user defined in the first LDAP server"):
login_and_execute_query(username="user1", password="user1")
with And("I should be able to login and execute query again using a user defined in the second LDAP server"):
login_and_execute_query(username="user2", password="user2")
@TestScenario
def dynamically_added_users(self, node="clickhouse1", count=10):
"""Check that we can restart ClickHouse server when one
LDAP external user directory is configured and the login
with an LDAP users that are dynamically added after restart.
"""
self.context.node = self.context.cluster.node(node)
servers = {
"openldap1": {
"host": "openldap1",
"port": "389",
"enable_tls": "no",
"auth_dn_prefix": "cn=",
"auth_dn_suffix": ",ou=users,dc=company,dc=com"
},
}
with ldap_servers(servers):
with rbac_roles("ldap_role") as roles:
with ldap_external_user_directory(server="openldap1", roles=roles, restart=True):
with Given("I login and execute query using existing LDAP user"):
login_and_execute_query(username="user1", password="user1")
with When("I then restart the server"):
restart()
with Then("after restart I should be able to login and execute query using existing LDAP user"):
login_and_execute_query(username="user1", password="user1")
dynamic_users = []
with When("I define dynamically added LDAP users"):
for i in range(count):
dynamic_users.append(
{"cn": f"dynamic_user{i}", "userpassword": randomword(20)}
)
with ldap_users(*dynamic_users, node=self.context.cluster.node("openldap1")):
with Then("I should be able to login and execute queries using dynamically added users"):
for dynamic_user in dynamic_users:
with When(f"using dynamically added user {dynamic_user['cn']}"):
login_and_execute_query(username=dynamic_user["cn"], password=dynamic_user["userpassword"])
@TestScenario
@Requirements(
RQ_SRS_009_LDAP_ExternalUserDirectory_Restart_Server_ParallelLogins("1.0")
)
def parallel_login(self, server=None, user_count=10, timeout=200):
"""Check that login of valid and invalid users works in parallel
using local users defined using RBAC and LDAP users authenticated using
multiple LDAP external user directories when server is restarted
in the middle of parallel login attempts. After server is restarted
makes sure that parallel logins work as expected.
"""
servers = {
"openldap1": {
"host": "openldap1",
"port": "389",
"enable_tls": "no",
"auth_dn_prefix": "cn=",
"auth_dn_suffix": ",ou=users,dc=company,dc=com"
},
"openldap2": {
"host": "openldap2",
"port": "636",
"enable_tls": "yes",
"auth_dn_prefix": "cn=",
"auth_dn_suffix": ",ou=users,dc=company,dc=com",
"tls_require_cert": "never",
}
}
with Given("I have two LDAP servers"):
entries = [
(["openldap1"], []),
(["openldap2"], [])
]
with And("I define a group of users to be created on each LDAP server"):
user_groups = {
"openldap1_users": [{"cn": f"openldap1_parallel_user{i}", "userpassword": randomword(20)} for i in
range(user_count)],
"openldap2_users": [{"cn": f"openldap2_parallel_user{i}", "userpassword": randomword(20)} for i in
range(user_count)],
"local_users": [{"cn": f"local_parallel_user{i}", "userpassword": randomword(20)} for i in
range(user_count)]
}
@TestStep(When)
@Name("I login as {username} and execute query")
def login_and_execute_query_during_restart(self, username, password, exitcode, message, steps=True, timeout=60):
"""Execute a query and ignore exitcode and message as
during restart exit codes and messages vary based on the state
of the restarted container and the ClickHouse server
and there are too many cases and complete list is not fully known
therefore trying to list all possible cases produces random fails.
"""
r = self.context.cluster.command(None, f"{self.context.cluster.docker_compose} exec {self.context.node.name} " +
f"clickhouse client -q \"SELECT 1\" --user {username} --password {password}", steps=steps, timeout=timeout)
return r
@TestStep(When)
@Name("I login as {username} and execute query")
def login_and_execute_query(self, username, password, exitcode=None, message=None, steps=True, timeout=60):
self.context.node.query("SELECT 1",
settings=[("user", username), ("password", password)],
exitcode=exitcode or 0,
message=message, steps=steps, timeout=timeout)
def login_with_valid_username_and_password(users, i, iterations=10, during_restart=False):
"""Login with valid username and password.
"""
query = login_and_execute_query
if during_restart:
query = login_and_execute_query_during_restart
with When(f"valid users try to login #{i}"):
for i in range(iterations):
random_user = users[random.randint(0, len(users) - 1)]
query(username=random_user["cn"], password=random_user["userpassword"],
exitcode=0, message="1", steps=False)
def login_with_valid_username_and_invalid_password(users, i, iterations=10, during_restart=False):
"""Login with valid username and invalid password.
"""
query = login_and_execute_query
if during_restart:
query = login_and_execute_query_during_restart
with When(f"users try to login with valid username and invalid password #{i}"):
for i in range(iterations):
random_user = users[random.randint(0, len(users) - 1)]
query(username=random_user["cn"],
password=(random_user["userpassword"] + randomword(1)),
exitcode=4,
message=f"DB::Exception: {random_user['cn']}: Authentication failed: password is incorrect or there is no user with such name",
steps=False)
def login_with_invalid_username_and_valid_password(users, i, iterations=10, during_restart=False):
"""Login with invalid username and valid password.
"""
query = login_and_execute_query
if during_restart:
query = login_and_execute_query_during_restart
with When(f"users try to login with invalid username and valid password #{i}"):
for i in range(iterations):
random_user = dict(users[random.randint(0, len(users) - 1)])
random_user["cn"] += randomword(1)
query(username=random_user["cn"],
password=random_user["userpassword"],
exitcode=4,
message=f"DB::Exception: {random_user['cn']}: Authentication failed: password is incorrect or there is no user with such name",
steps=False)
with And("I have a list of checks that I want to run for each user group"):
checks = [
login_with_valid_username_and_password,
login_with_valid_username_and_invalid_password,
login_with_invalid_username_and_valid_password
]
with And("I create config file to define LDAP external user directory for each LDAP server"):
config = create_entries_ldap_external_user_directory_config_content(entries)
with ldap_servers(servers):
with ldap_external_user_directory(server=None, roles=None, restart=True, config=config):
with ldap_users(*user_groups["openldap1_users"], node=self.context.cluster.node("openldap1")):
with ldap_users(*user_groups["openldap2_users"], node=self.context.cluster.node("openldap2")):
with rbac_users(*user_groups["local_users"]):
tasks = []
try:
with When("I restart the server during parallel login of users in each group"):
p = Pool(10)
for users in user_groups.values():
for check in checks:
tasks.append(p.apply_async(check, (users, 0, 25, True)))
tasks.append(p.apply_async(restart))
finally:
with Then("logins during restart should work"):
join(tasks, timeout)
tasks = []
try:
with When("I perform parallel login of users in each group after restart"):
p = Pool(10)
for users in user_groups.values():
for check in checks:
tasks.append(p.apply_async(check, (users, 0, 10, False)))
finally:
with Then("logins after restart should work"):
join(tasks, timeout)
@TestOutline(Feature)
@Name("restart")
@Requirements(
RQ_SRS_009_LDAP_ExternalUserDirectory_Restart_Server("1.0")
)
def feature(self, servers=None, server=None, node="clickhouse1"):
"""Check that we can restart ClickHouse server
when one or more external user directories are configured.
"""
self.context.node = self.context.cluster.node(node)
for scenario in loads(current_module(), Scenario):
Scenario(test=scenario, flags=TE)()