2026-03-25 07:26:04 +01:00
< ? php
namespace MintyPHP\Repository\Tenant ;
use MintyPHP\DB ;
/** Persists LDAP authentication settings per tenant, including encrypted bind credentials. */
class TenantLdapAuthRepository implements TenantLdapAuthRepositoryInterface
{
private const COLUMNS = 'id, tenant_id, enabled, enforce_ldap_login, host, port, encryption_mode, verify_tls_certificate, base_dn, bind_dn_enc, bind_password_enc, user_search_filter, user_search_scope, bind_method, bind_username_format, unique_id_attribute, attribute_map, sync_profile_on_login, sync_profile_fields, allowed_domains, auto_remember_mode, network_timeout, created, modified' ;
private function unwrap ( $row ) : ? array
{
if ( ! $row || ! is_array ( $row )) {
return null ;
}
if ( isset ( $row [ 'tenant_auth_ldap' ]) && is_array ( $row [ 'tenant_auth_ldap' ])) {
return $row [ 'tenant_auth_ldap' ];
}
return $row ;
}
public function findByTenantId ( int $tenantId ) : ? array
{
$row = DB :: selectOne (
'select ' . self :: COLUMNS . ' from tenant_auth_ldap where tenant_id = ? limit 1' ,
( string ) $tenantId
);
return $this -> unwrap ( $row );
}
public function listByTenantIds ( array $tenantIds ) : array
{
$tenantIds = array_values ( array_unique ( array_map ( 'intval' , $tenantIds )));
$tenantIds = array_values ( array_filter ( $tenantIds , static fn ( $id ) => $id > 0 ));
if ( ! $tenantIds ) {
return [];
}
$placeholders = implode ( ',' , array_fill ( 0 , count ( $tenantIds ), '?' ));
$rows = DB :: select (
'select ' . self :: COLUMNS . ' from tenant_auth_ldap where tenant_id in (' . $placeholders . ')' ,
... array_map ( 'strval' , $tenantIds )
);
if ( ! is_array ( $rows )) {
return [];
}
$result = [];
foreach ( $rows as $row ) {
$item = $this -> unwrap ( $row );
if ( ! is_array ( $item )) {
continue ;
}
$tenantId = ( int ) ( $item [ 'tenant_id' ] ? ? 0 );
if ( $tenantId <= 0 ) {
continue ;
}
$result [ $tenantId ] = $item ;
}
return $result ;
}
public function upsertByTenantId ( int $tenantId , array $data ) : bool
{
$autoRememberMode = $data [ 'auto_remember_mode' ] ? ? null ;
$autoRememberModeParam = $autoRememberMode !== null ? ( string ) ( int ) $autoRememberMode : null ;
$attributeMap = $data [ 'attribute_map' ] ? ? '{"first_name":"givenName","last_name":"sn","email":"mail","phone":"telephoneNumber","mobile":"mobile"}' ;
if ( is_array ( $attributeMap )) {
$attributeMap = json_encode ( $attributeMap , JSON_THROW_ON_ERROR );
}
$result = DB :: update (
'insert into tenant_auth_ldap (tenant_id, enabled, enforce_ldap_login, host, port, encryption_mode, verify_tls_certificate, base_dn, bind_dn_enc, bind_password_enc, user_search_filter, user_search_scope, bind_method, bind_username_format, unique_id_attribute, attribute_map, sync_profile_on_login, sync_profile_fields, allowed_domains, auto_remember_mode, network_timeout, created) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,NOW()) ' .
'on duplicate key update enabled = values(enabled), enforce_ldap_login = values(enforce_ldap_login), host = values(host), port = values(port), encryption_mode = values(encryption_mode), verify_tls_certificate = values(verify_tls_certificate), base_dn = values(base_dn), bind_dn_enc = values(bind_dn_enc), bind_password_enc = values(bind_password_enc), ' .
'user_search_filter = values(user_search_filter), user_search_scope = values(user_search_scope), bind_method = values(bind_method), bind_username_format = values(bind_username_format), unique_id_attribute = values(unique_id_attribute), attribute_map = values(attribute_map), ' .
'sync_profile_on_login = values(sync_profile_on_login), sync_profile_fields = values(sync_profile_fields), allowed_domains = values(allowed_domains), auto_remember_mode = values(auto_remember_mode), network_timeout = values(network_timeout), modified = NOW()' ,
( string ) $tenantId ,
! empty ( $data [ 'enabled' ]) ? '1' : '0' ,
! empty ( $data [ 'enforce_ldap_login' ]) ? '1' : '0' ,
$data [ 'host' ] ? ? '' ,
( string ) ( int ) ( $data [ 'port' ] ? ? 389 ),
$data [ 'encryption_mode' ] ? ? 'starttls' ,
! empty ( $data [ 'verify_tls_certificate' ]) ? '1' : '0' ,
$data [ 'base_dn' ] ? ? '' ,
$data [ 'bind_dn_enc' ] ? ? null ,
$data [ 'bind_password_enc' ] ? ? null ,
$data [ 'user_search_filter' ] ? ? '(&(objectClass=user)(sAMAccountName=%s))' ,
$data [ 'user_search_scope' ] ? ? 'sub' ,
$data [ 'bind_method' ] ? ? 'search_then_bind' ,
$data [ 'bind_username_format' ] ? ? null ,
$data [ 'unique_id_attribute' ] ? ? 'objectGUID' ,
$attributeMap ,
! empty ( $data [ 'sync_profile_on_login' ]) ? '1' : '0' ,
$data [ 'sync_profile_fields' ] ? ? null ,
$data [ 'allowed_domains' ] ? ? null ,
$autoRememberModeParam ,
( string ) ( int ) ( $data [ 'network_timeout' ] ? ? 5 )
);
return $result !== false ;
}
2026-04-07 14:35:57 +02:00
public function findEnabledWithExplicitDomain ( string $domain ) : array
{
$domain = strtolower ( trim ( $domain ));
if ( $domain === '' ) {
return [];
}
$rows = DB :: select (
" select tenant_id, allowed_domains from tenant_auth_ldap where enabled = 1 and allowed_domains is not null and allowed_domains != '' and FIND_IN_SET(?, allowed_domains) > 0 " ,
$domain
);
if ( ! is_array ( $rows )) {
return [];
}
$result = [];
foreach ( $rows as $row ) {
$item = $this -> unwrap ( $row );
if ( ! is_array ( $item )) {
continue ;
}
$tenantId = ( int ) ( $item [ 'tenant_id' ] ? ? 0 );
if ( $tenantId <= 0 ) {
continue ;
}
$result [] = [ 'tenant_id' => $tenantId , 'allowed_domains' => ( string ) ( $item [ 'allowed_domains' ] ? ? '' )];
}
return $result ;
}
2026-03-25 07:26:04 +01:00
}