diff --git a/config/services.yaml b/config/services.yaml index 25662b1..0c15c6f 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -45,6 +45,15 @@ services: $LDAPCertificateCheckingStrategy: "%env(LDAP_CERTIFICATE_CHECKING_STRATEGY)%" $autoCreate: "%env(bool:LDAP_AUTH_USER_AUTOCREATE)%" + App\Services\LDAPFallbackAuth: + arguments: + $LDAPAuthUrl: "%env(LDAP_AUTH_URL)%" + $LDAPDnPattern: "%env(LDAP_DN_PATTERN)%" + $LDAPMailAttribute: "%env(LDAP_MAIL_ATTRIBUTE)%" + $LDAPCertificateCheckingStrategy: "%env(LDAP_CERTIFICATE_CHECKING_STRATEGY)%" + $autoCreate: "%env(bool:LDAP_AUTH_USER_AUTOCREATE)%" + $whichFirst: "%env(AUTH_WHICH_PROVIDER_FIRST)%" + # controllers are imported separately to make sure services can be injected # as action arguments even if you don't extend any base controller class App\Controller\: diff --git a/src/Controller/DAVController.php b/src/Controller/DAVController.php index abb1e5d..18b23d3 100644 --- a/src/Controller/DAVController.php +++ b/src/Controller/DAVController.php @@ -11,6 +11,7 @@ use App\Services\BirthdayService; use App\Services\IMAPAuth; use App\Services\LDAPAuth; +use App\Services\LDAPFallbackAuth; use Doctrine\ORM\EntityManagerInterface; use PDO; use Psr\Log\LoggerInterface; @@ -27,6 +28,7 @@ class DAVController extends AbstractController public const AUTH_BASIC = 'Basic'; public const AUTH_IMAP = 'IMAP'; public const AUTH_LDAP = 'LDAP'; + public const AUTH_LDAP_AND_BASIC = 'BasicAndLDAP'; /** * Is CalDAV enabled? @@ -135,6 +137,13 @@ class DAVController extends AbstractController */ protected $LDAPAuthBackend; + /** + * LDAP with Fallback Auth Backend class. + * + * @var LDAPFallbackAuth + */ + protected $LDAPFallbackAuthBackend; + /** * Logger for exceptions. * @@ -149,7 +158,7 @@ class DAVController extends AbstractController */ protected $server; - public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend, IMAPAuth $IMAPAuthBackend, LDAPAuth $LDAPAuthBackend, UrlGeneratorInterface $router, EntityManagerInterface $entityManager, LoggerInterface $logger, BirthdayService $birthdayService, string $publicDir, bool $calDAVEnabled = true, bool $cardDAVEnabled = true, bool $webDAVEnabled = false, bool $publicCalendarsEnabled = true, ?string $inviteAddress = null, ?string $authMethod = null, ?string $authRealm = null, ?string $webdavPublicDir = null, ?string $webdavHomesDir = null, ?string $webdavTmpDir = null) + public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend, IMAPAuth $IMAPAuthBackend, LDAPAuth $LDAPAuthBackend, LDAPFallbackAuth $LDAPFallbackAuthBackend, UrlGeneratorInterface $router, EntityManagerInterface $entityManager, LoggerInterface $logger, BirthdayService $birthdayService, string $publicDir, bool $calDAVEnabled = true, bool $cardDAVEnabled = true, bool $webDAVEnabled = false, bool $publicCalendarsEnabled = true, ?string $inviteAddress = null, ?string $authMethod = null, ?string $authRealm = null, ?string $webdavPublicDir = null, ?string $webdavHomesDir = null, ?string $webdavTmpDir = null) { $this->publicDir = $publicDir; @@ -172,6 +181,7 @@ public function __construct(MailerInterface $mailer, BasicAuth $basicAuthBackend $this->basicAuthBackend = $basicAuthBackend; $this->IMAPAuthBackend = $IMAPAuthBackend; $this->LDAPAuthBackend = $LDAPAuthBackend; + $this->LDAPFallbackAuthBackend = $LDAPFallbackAuthBackend; $this->initServer($authMethod, $authRealm); $this->initExceptionListener(); @@ -200,6 +210,9 @@ private function initServer(string $authMethod, string $authRealm = User::DEFAUL case self::AUTH_LDAP: $authBackend = $this->LDAPAuthBackend; break; + case self::AUTH_LDAP_AND_BASIC: + $authBackend = $this->LDAPFallbackAuthBackend; + break; case self::AUTH_BASIC: default: $authBackend = $this->basicAuthBackend; diff --git a/src/Services/LDAPFallbackAuth.php b/src/Services/LDAPFallbackAuth.php new file mode 100644 index 0000000..2826256 --- /dev/null +++ b/src/Services/LDAPFallbackAuth.php @@ -0,0 +1,82 @@ +LDAPAuth = new LDAPAuth($doctrine, $utils, $LDAPAuthUrl, $LDAPDnPattern, $LDAPMailAttribute ?? 'mail', $autoCreate, $LDAPCertificateCheckingStrategy ?? 'try' ); + $this->BasicAuth = new BasicAuth($doctrine, $utils); + $this->whichFirst = $whichFirst ?? PROVIDER_BASIC; + + $this->doctrine = $doctrine; + $this->utils = $utils; + } + + /** + * Validates a username and password by trying to authenticate against LDAP and local database. + * + * @param string $username + * @param string $password + */ + protected function validateUserPass($username, $password): bool + { + /* + * Use the backends. + */ + switch ($this->whichFirst) { + case self::PROVIDER_BASIC: + if(!$this->BasicAuth->validateUserPass($username, $password)){ + return $this->LDAPAuth->validateUserPass($username, $password); + }else{ + return true; + } + case self::PROVIDER_LDAP: + if(!$this->LDAPAuth->validateUserPass($username, $password)){ + return $this->BasicAuth->validateUserPass($username, $password); + }else{ + return true; + } + } + return false; + } +}