Initial commit with first working alpha. 51/30251/2 master
authorAlexander Pankow <alexander.pankow@bpanet.de>
Wed, 21 May 2014 11:42:37 +0000 (13:42 +0200)
committerAlexander Pankow <info@alexander-pankow.de>
Wed, 21 May 2014 12:37:06 +0000 (14:37 +0200)
Change-Id: I5b827fa7b6986b0e189f67ecd499442bda746f7d
Reviewed-on: https://review.typo3.org/30251
Reviewed-by: Alexander Pankow
Tested-by: Alexander Pankow
19 files changed:
Classes/Controller/LDAPController.php [new file with mode: 0644]
Classes/Domain/Model/Config.php [new file with mode: 0644]
Classes/Domain/Repository/ConfigRepository.php [new file with mode: 0644]
Classes/Exception/ConfigurationException.php [new file with mode: 0644]
Classes/Exception/ConnectionException.php [new file with mode: 0644]
Classes/Exception/LDAPException.php [new file with mode: 0644]
Classes/Utility/LDAPUtility.php [new file with mode: 0644]
Configuration/TCA/tx_apldap_domain_model_config.php [new file with mode: 0644]
Resources/Private/Language/locallang.xml [new file with mode: 0644]
Resources/Private/Language/locallang_db.xml [new file with mode: 0644]
Resources/Private/Language/locallang_mod.xml [new file with mode: 0644]
Resources/Private/Layouts/Default.html [new file with mode: 0644]
Resources/Private/Templates/LDAP/List.html [new file with mode: 0644]
Resources/Public/Icons/ldap_configuration.png [new file with mode: 0644]
ext_conf_template.txt [new file with mode: 0644]
ext_emconf.php [new file with mode: 0644]
ext_icon.png [new file with mode: 0644]
ext_tables.php [new file with mode: 0644]
ext_tables.sql [new file with mode: 0644]

diff --git a/Classes/Controller/LDAPController.php b/Classes/Controller/LDAPController.php
new file mode 100644 (file)
index 0000000..89b35fc
--- /dev/null
@@ -0,0 +1,82 @@
+<?php
+namespace AP\ApLdap\Controller;
+
+use AP\ApLdap\Exception\LDAPException;
+use TYPO3\CMS\Core\Utility\GeneralUtility,
+       AP\ApLdap\Utility\LDAPUtility,
+       AP\ApLdap\Exception\ConnectionException,
+       \TYPO3\CMS\Core\Messaging\FlashMessage,
+       \TYPO3\CMS\Extbase\Utility\LocalizationUtility,
+       TYPO3\CMS\Core\Utility\DebugUtility;
+
+/**
+ * LDAP backend module controller
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+class LDAPController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
+
+       /**
+        * Redirects to list action
+        */
+       public function indexAction() {
+               $this->forward('list');
+       }
+
+       /**
+        * Lists all configurations
+        */
+       public function listAction() {
+               /** @var \AP\ApLdap\Domain\Repository\ConfigRepository $configRepository */
+               $configRepository = GeneralUtility::makeInstance('AP\\ApLdap\\Domain\\Repository\\ConfigRepository');
+               $ldapConfigs = $configRepository->findAll();
+
+               $this->view->assign('ldapConfigs', $ldapConfigs);
+       }
+
+       /**
+        * Redirect to creation form to create a new configuration
+        */
+       public function newAction() {
+               $this->redirectToUri("alt_doc.php?edit[tx_apldap_domain_model_config][0]=new&returnUrl=mod.php?M=tools_ApLdapLdap");
+       }
+
+       /**
+        * Redirects to edit form to edit this configuration
+        *
+        * @param int $configUid
+        */
+       public function editAction($configUid) {
+               $this->redirectToUri("alt_doc.php?edit[tx_apldap_domain_model_config][$configUid]=edit&returnUrl=mod.php?M=tools_ApLdapLdap");
+       }
+
+       /**
+        * Check LDAP configuration; trying to connect and bind against LDAP server
+        *
+        * @param int $configUid
+        */
+       public function checkConfigAction($configUid) {
+               /** @var \AP\ApLdap\Utility\LDAPUtility $ldapUtility */
+               $ldapUtility = $this->objectManager->get('AP\\ApLdap\\Utility\\LDAPUtility');
+               try {
+                       $ldapUtility->connect($configUid);
+                       $ldapUtility->bind();
+                       $ldapUtility->disconnect();
+
+                       // set flash message
+                       $title = LocalizationUtility::translate('list.checkConfig.ok.title', $this->extensionName);
+                       $message = LocalizationUtility::translate('list.checkConfig.ok.message', $this->extensionName);
+                       $this->controllerContext->getFlashMessageContainer()->add($message, $title, FlashMessage::OK);
+               } catch (LDAPException $e) {
+                       $title = LocalizationUtility::translate('list.checkConfig.failed.title', $this->extensionName);
+                       $message = $e->getMessage();
+                       if ($e instanceof ConnectionException)
+                               $message .= ': ' . $e->getLdapMessage() . ' [' . $e->getLdapCode() . ']';
+                       $this->controllerContext->getFlashMessageContainer()->add($message, $title, FlashMessage::ERROR);
+               }
+
+               $this->forward('index');
+       }
+}
diff --git a/Classes/Domain/Model/Config.php b/Classes/Domain/Model/Config.php
new file mode 100644 (file)
index 0000000..b57c2c8
--- /dev/null
@@ -0,0 +1,185 @@
+<?php
+namespace AP\ApLdap\Domain\Model;
+
+/**
+ * LDAP configuration model
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+class Config extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
+       const LDAP_TYPE_OPENLDAP = 0;
+       const LDAP_TYPE_ACTIVEDIRECTORY = 1;
+
+       /**
+        * @var bool
+        */
+       protected $hidden;
+
+       /**
+        * @var string
+        */
+       protected $name;
+
+       /**
+        * @var string
+        */
+       protected $ldapType;
+
+       /**
+        * @var int
+        */
+       protected $ldapProtocol;
+
+       /**
+        * @var string
+        */
+       protected $ldapHost;
+
+       /**
+        * @var int
+        */
+       protected $ldapPort;
+
+       /**
+        * @var bool
+        */
+       protected $ldapUseTls;
+
+       /**
+        * @var string
+        */
+       protected $ldapBindDn;
+
+       /**
+        * @var string
+        */
+       protected $ldapPassword;
+
+       /**
+        * @param boolean $hidden
+        */
+       public function setHidden($hidden) {
+               $this->hidden = $hidden;
+       }
+
+       /**
+        * @return boolean
+        */
+       public function getHidden() {
+               return $this->hidden;
+       }
+
+       /**
+        * @param string $ldapBindDn
+        */
+       public function setLdapBindDn($ldapBindDn) {
+               $this->ldapBindDn = $ldapBindDn;
+       }
+
+       /**
+        * @return string
+        */
+       public function getLdapBindDn() {
+               return $this->ldapBindDn;
+       }
+
+       /**
+        * @param string $ldapHost
+        */
+       public function setLdapHost($ldapHost) {
+               $this->ldapHost = $ldapHost;
+       }
+
+       /**
+        * @return string
+        */
+       public function getLdapHost() {
+               return $this->ldapHost;
+       }
+
+       /**
+        * @param string $ldapPassword
+        */
+       public function setLdapPassword($ldapPassword) {
+               $this->ldapPassword = $ldapPassword;
+       }
+
+       /**
+        * @return string
+        */
+       public function getLdapPassword() {
+               return $this->ldapPassword;
+       }
+
+       /**
+        * @param int $ldapPort
+        */
+       public function setLdapPort($ldapPort) {
+               $this->ldapPort = $ldapPort;
+       }
+
+       /**
+        * @return int
+        */
+       public function getLdapPort() {
+               return $this->ldapPort;
+       }
+
+       /**
+        * @param boolean $ldapUseTls
+        */
+       public function setLdapUseTls($ldapUseTls) {
+               $this->ldapUseTls = $ldapUseTls;
+       }
+
+       /**
+        * @return boolean
+        */
+       public function getLdapUseTls() {
+               return $this->ldapUseTls;
+       }
+
+       /**
+        * @param int $ldapProtocol
+        */
+       public function setLdapProtocol($ldapProtocol) {
+               $this->ldapProtocol = $ldapProtocol;
+       }
+
+       /**
+        * @return int
+        */
+       public function getLdapProtocol() {
+               return $this->ldapProtocol;
+       }
+
+       /**
+        * @param string $ldapServer
+        */
+       public function setLdapType($ldapServer) {
+               $this->ldapType = $ldapServer;
+       }
+
+       /**
+        * @return string
+        */
+       public function getLdapType() {
+               return $this->ldapType;
+       }
+
+       /**
+        * @param string $name
+        */
+       public function setName($name) {
+               $this->name = $name;
+       }
+
+       /**
+        * @return string
+        */
+       public function getName() {
+               return $this->name;
+       }
+}
diff --git a/Classes/Domain/Repository/ConfigRepository.php b/Classes/Domain/Repository/ConfigRepository.php
new file mode 100644 (file)
index 0000000..626331e
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+namespace AP\ApLdap\Domain\Repository;
+
+/**
+ * LDAP configuration repository
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+class ConfigRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {}
diff --git a/Classes/Exception/ConfigurationException.php b/Classes/Exception/ConfigurationException.php
new file mode 100644 (file)
index 0000000..ed8a263
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+namespace AP\ApLdap\Exception;
+
+/**
+ * LDAP configuration exception. Throw if there are any errors with the configuration
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+class ConfigurationException extends LDAPException {}
diff --git a/Classes/Exception/ConnectionException.php b/Classes/Exception/ConnectionException.php
new file mode 100644 (file)
index 0000000..77de71f
--- /dev/null
@@ -0,0 +1,47 @@
+<?php
+namespace AP\ApLdap\Exception;
+
+/**
+ * LDAP configuration exception. Throw if there are any errors while connecting or binding against ldap server.
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+class ConnectionException extends LDAPException {
+       /**
+        * @var resource
+        */
+       protected $ldapConnection;
+
+       /**
+        * @param resource $ldapConnection
+        * @param string $additionalMessage
+        * @param \Exception $previous
+        */
+       public function __construct(&$ldapConnection, $additionalMessage = '', \Exception $previous = null) {
+               $this->ldapConnection = $ldapConnection;
+               $this->message = $additionalMessage;
+       }
+
+       /**
+        * @return string
+        */
+       public function __toString() {
+               return __CLASS__ . ": " . ldap_err2str(ldap_errno($this->ldapConnection)) . "\n";
+       }
+
+       /**
+        * @return string
+        */
+       public function getLdapMessage() {
+               return ldap_error($this->ldapConnection);
+       }
+
+       /**
+        * @return int
+        */
+       public function getLdapCode() {
+               return ldap_errno($this->ldapConnection);
+       }
+}
diff --git a/Classes/Exception/LDAPException.php b/Classes/Exception/LDAPException.php
new file mode 100644 (file)
index 0000000..86c39a8
--- /dev/null
@@ -0,0 +1,11 @@
+<?php
+namespace AP\ApLdap\Exception;
+
+/**
+ * LDAP exception. Base exception for this extension. It is abstract, so the other exceptions have to extend this class.
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+abstract class LDAPException extends \Exception {}
diff --git a/Classes/Utility/LDAPUtility.php b/Classes/Utility/LDAPUtility.php
new file mode 100644 (file)
index 0000000..e0f2e76
--- /dev/null
@@ -0,0 +1,382 @@
+<?php
+namespace AP\ApLdap\Utility;
+
+use AP\ApLdap\Exception\ConnectionException;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility,
+       AP\ApLdap\Domain\Model\Config,
+       AP\ApLdap\Exception\ConfigurationException;
+
+/**
+ * LDAP utility
+ *
+ * @package TYPO3
+ * @subpackage tx_apldap
+ * @author Alexander Pankow <info@alexander-pankow.de>
+ */
+class LDAPUtility {
+
+       /**
+        * @var Config
+        */
+       protected $config = null;
+
+       /**
+        * LDAP connection resource
+        *
+        * @var resource|null
+        */
+       protected $connection = null;
+
+       /**
+        * LDAP bind resource
+        *
+        * @var resource|null
+        */
+       protected $bind = null;
+
+       /**
+        * @var \AP\ApLdap\Domain\Repository\ConfigRepository|null
+        */
+       protected $configRepository = null;
+
+
+       /**
+        * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface
+        */
+       protected $objectManager = null;
+
+       /**
+        * Last stored resources from ldap_search()
+        *
+        * @var null|resource
+        */
+       protected $lastSearch = null;
+
+       /**
+        * Last stored resources from ldap_first_entry(), ldap_next_entry()
+        *
+        * @var null|resource
+        */
+       protected $lastEntry = null;
+
+       /**
+        * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
+        */
+       public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager = null) {
+               if ($objectManager === null)
+                       $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
+               else
+                       $this->objectManager = $objectManager;
+       }
+
+       /**
+        * Connects to a specified server
+        *
+        * @param int $configId
+        * @return bool
+        * @throws \AP\ApLdap\Exception\ConnectionException
+        */
+       public function connect($configId = 0) {
+               $this->initConfig($configId);
+
+               if (!$this->connection = @ldap_connect($this->getConfig()->getLdapHost(), $this->getConfig()->getLdapPort()))
+                       throw new ConnectionException($this->connection, 'Can\'t connect to LDAP server ' . $this->getConfig()->getLdapHost());
+
+               @ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->getConfig()->getLdapProtocol());
+
+               // Active Directory (User@Domain) configuration.
+               if ($this->getConfig()->getLdapType() == Config::LDAP_TYPE_ACTIVEDIRECTORY)
+                       @ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0);
+
+               if ($this->getConfig()->getLdapUseTls()) {
+                       if (!@ldap_start_tls($this->connection))
+                               throw new ConnectionException($this->connection, 'Start TLS failed');
+               }
+
+               return true;
+       }
+
+
+       /**
+        * @param int $configId
+        * @throws \AP\ApLdap\Exception\ConfigurationException
+        */
+       protected function initConfig($configId = 0) {
+               // check if `ldap` php extension is installed loaded
+               if (!extension_loaded('ldap'))
+                       throw new ConfigurationException('The LDAP php extension is not installed or not loaded.');
+
+               $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['ap_ldap']);
+               if (empty($configId))
+                       $configId = $extConf['defaultConfigurationUid'];
+
+               $config = $this->getConfigRepository()->findByUid($configId);
+               if (!$config)
+                       throw new ConfigurationException('LDAP configuration with id `' . $configId . '` not found.');
+
+               $this->config = $config;
+       }
+
+       /**
+        *
+        */
+       public function disconnect() {
+               $this->checkIfConnected();
+               @ldap_close($this->connection);
+       }
+
+       /**
+        * @param string $bindDn
+        * @param string $bindPw
+        * @return bool
+        * @throws \AP\ApLdap\Exception\ConnectionException
+        */
+       public function bind($bindDn = '', $bindPw = '') {
+               $this->checkIfConnected();
+
+               if (empty($bindDn))
+                       $bindDn = $this->getConfig()->getLdapBindDn();
+               if (empty($bindPw))
+                       $bindPw = $this->getConfig()->getLdapPassword();
+
+               if (!$this->bind = @ldap_bind($this->connection, $bindDn, $bindPw))
+                       throw new ConnectionException($this->connection, 'Bind failed');
+
+               return true;
+       }
+
+       /**
+        * @param $baseDn
+        * @param $filter
+        * @param array $attributes
+        * @param bool $attributesOnly
+        * @param int $sizeLimit
+        * @param int $timeLimit
+        * @param int $deRef
+        * @return LDAPUtility
+        * @throws \AP\ApLdap\Exception\ConnectionException
+        */
+       public function search($baseDn, $filter, $attributes = array(), $attributesOnly = false, $sizeLimit = 0, $timeLimit = 0, $deRef = LDAP_DEREF_NEVER) {
+               $this->checkIfConnected();
+
+               if (!$search = @ldap_search($this->connection, $baseDn, $filter, $attributes, $attributesOnly, $sizeLimit, $timeLimit, $deRef))
+                       throw new ConnectionException($this->connection, 'Search failed');
+
+               $this->lastSearch = $search;
+
+               return $this;
+       }
+
+       /**
+        * @param null|resource $search
+        * @return array|null
+        */
+       public function getEntries($search = null) {
+               if ($this->lastSearch === null && $search === null)
+                       return null;
+
+               if ($search === null)
+                       $search = $this->lastSearch;
+
+               return ldap_get_entries($this->connection, $search);
+       }
+
+       /**
+        * @param null|resource $search
+        * @return LDAPUtility
+        */
+       public function getFirstEntry($search = null) {
+               if ($this->lastSearch === null && $search === null)
+                       return null;
+
+               if ($search === null)
+                       $search = $this->lastSearch;
+
+               $this->lastEntry = ldap_first_entry($this->connection, $search);
+
+               if ($this->lastEntry === false)
+                       return false;
+
+               return $this;
+       }
+
+       /**
+        * @param null|resource $lastEntry
+        * @return LDAPUtility|boolean false if no more entries in the result
+        */
+       public function getNextEntry($lastEntry = null) {
+               if ($this->lastEntry === null && $lastEntry === null)
+                       return $this->getFirstEntry();
+
+               if ($lastEntry === null)
+                       $lastEntry = $this->lastEntry;
+
+               $this->lastEntry = ldap_next_entry($this->connection, $lastEntry);
+
+               if ($this->lastEntry === false)
+                       return false;
+
+               return $this;
+       }
+
+       /**
+        * @param null|resource $entry
+        * @return null|string
+        */
+       public function getDN($entry = null) {
+               if ($this->lastEntry === null && $entry === null)
+                       return null;
+
+               if ($entry === null)
+                       $entry = $this->lastEntry;
+
+               if ($entry === false)
+                       return false;
+
+               return ldap_get_dn($this->connection, $entry);
+       }
+
+       /**
+        * @param null|resource $search
+        * @return int|null
+        */
+       public function countEntries($search = null) {
+               if ($this->lastSearch === null && $search === null)
+                       return null;
+
+               if ($search === null)
+                       $search = $this->lastSearch;
+
+               return ldap_count_entries($this->connection, $search);
+       }
+
+       /**
+        * @param null|resource $entry
+        * @param string $attribute
+        * @return array|null|bool
+        */
+       public function getValues($attribute = '', $entry = null) {
+               if (($this->lastEntry === null && $entry === null) || empty($attribute))
+                       return null;
+
+               if ($entry === null)
+                       $entry = $this->lastEntry;
+
+               if ($entry === false)
+                       return false;
+
+               return ldap_get_values($this->connection, $entry, $attribute);
+       }
+
+       /**
+        * @param null|resource $entry
+        * @param string $attribute
+        * @return array|null|bool
+        */
+       public function getBinaryValues($attribute = '', $entry = null) {
+               if (($this->lastEntry === null && $entry === null) || empty($attribute))
+                       return null;
+
+               if ($entry === null)
+                       $entry = $this->lastEntry;
+
+               if ($entry === false)
+                       return false;
+
+               return ldap_get_values_len($this->connection, $entry, $attribute);
+       }
+
+       /**
+        * @param null $entry
+        * @return array|null|bool
+        */
+       public function getAttributes($entry = null) {
+               if ($this->lastEntry === null && $entry === null)
+                       return null;
+
+               if ($entry === null)
+                       $entry = $this->lastEntry;
+
+               if ($entry === false)
+                       return false;
+
+               $attributes = array();
+               $ldapAttributes = ldap_get_attributes($this->connection, $entry);
+               foreach ($ldapAttributes as $attribute => $value) {
+                       if (is_numeric($attribute))
+                               $attributes[] = $value;
+               }
+
+               return $attributes;
+       }
+
+       /**
+        * @return null|resource
+        */
+       public function getLastSearch() {
+               return $this->lastSearch;
+       }
+
+       /**
+        * @return null|resource
+        */
+       public function getLastEntry() {
+               return $this->lastEntry;
+       }
+
+       /**
+        * @return bool
+        * @throws \AP\ApLdap\Exception\ConnectionException
+        */
+       protected function checkIfConnected() {
+               if (!is_resource($this->connection))
+                       throw new ConnectionException($this->connection, 'Not connected');
+
+               return true;
+       }
+
+       /**
+        * @return null|resource
+        */
+       public function getConnectionResource() {
+               return $this->connection;
+       }
+
+       /**
+        * @return null|resource
+        */
+       public function getBindResource() {
+               return $this->bind;
+       }
+
+       /**
+        * @return int
+        */
+       public function getConfigUid() {
+               return $this->getConfig()->getUid();
+       }
+
+       /**
+        * @return Config|\AP\ApLdapAuth\Domain\Model\Config
+        */
+       public function getConfig() {
+               return $this->config;
+       }
+
+       /**
+        * @param string $className
+        */
+       public function setConfigRepository($className = 'AP\\ApLdap\\Domain\\Repository\\ConfigRepository') {
+               $this->configRepository = $this->objectManager->get($className);
+       }
+
+       /**
+        * @return \Ap\ApLdap\Domain\Repository\ConfigRepository|null
+        */
+       public function getConfigRepository() {
+               if ($this->configRepository === null)
+                       $this->setConfigRepository();
+               return $this->configRepository;
+       }
+}
diff --git a/Configuration/TCA/tx_apldap_domain_model_config.php b/Configuration/TCA/tx_apldap_domain_model_config.php
new file mode 100644 (file)
index 0000000..9a81d05
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+if (!defined ('TYPO3_MODE')) die ('Access denied.');
+
+$extKey = 'ap_ldap';
+$extPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath($extKey);
+
+return array(
+       'ctrl' => array(
+               'title' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.title',
+               'label' => 'name',
+               'adminOnly' => true,
+               'rootLevel' => 1,
+               'dividers2tabs' => true,
+               'tstamp' => 'tstamp',
+               'crdate' => 'crdate',
+               'cruser_id' => 'cruser_id',
+               'default_sortby' => 'ORDER BY name',
+               'delete' => 'deleted',
+               'enablecolumns' => array(
+                       'disabled' => 'hidden'
+               ),
+               'iconfile' => $extPath . 'ext_icon.png'
+       ),
+       'interface' => array(
+               'showRecordFieldList' => 'hidden,name,ldap_type,ldap_protocol,ldap_host,ldap_port,ldap_use_tls,ldap_bind_dn,ldap_password'
+       ),
+       'columns' => array(
+               'hidden' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
+                       'config' => array(
+                               'type' => 'check',
+                               'default' => '0'
+                       )
+               ),
+               'name' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.name',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'required,trim',
+                       )
+               ),
+               'ldap_type' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_type',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       array('LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_type.I.0', '0'),
+//                                     array('LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_type.I.1', '1')
+                               ),
+                               'size' => 1,
+                               'maxitems' => 1,
+                       )
+               ),
+               'ldap_protocol' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_protocol',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       array('LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_protocol.I.0', '3'),
+                                       array('LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_protocol.I.1', '2'),
+                               ),
+                               'size' => 1,
+                               'maxitems' => 1,
+                       )
+               ),
+               'ldap_host' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_host',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'max' => '255',
+                               'eval' => 'required,trim',
+                       )
+               ),
+               'ldap_port' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_port',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '5',
+                               'max' => '5',
+                               'eval' => 'int,trim',
+                               'default' => '389',
+                       )
+               ),
+               'ldap_use_tls' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_use_tls',
+                       'config' => array(
+                               'type' => 'check',
+                               'default' => 0
+                       )
+               ),
+               'ldap_bind_dn' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_bind_dn',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+               'ldap_password' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.ldap_password',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'max' => '255',
+                               'eval' => 'password',
+                       )
+               )
+       ),
+       'types' => array(
+               0 => array(
+                       'showitem' => '
+                               --div--;LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.tabs.general,name,
+                               --div--;LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xml:tx_apldap_domain_model_config.tabs.server, ldap_type, ldap_protocol, ldap_host, ldap_port, ldap_use_tls, ldap_bind_dn, ldap_password'
+               )
+       )
+);
diff --git a/Resources/Private/Language/locallang.xml b/Resources/Private/Language/locallang.xml
new file mode 100644 (file)
index 0000000..9741263
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+       <data type="array">
+               <languageKey index="default" type="array">
+                       <label index="list">Overview</label>
+                       <label index="list.title">LDAP Configurations</label>
+                       <label index="list.new">Add new configuration</label>
+                       <label index="list.edit">Edit configuration</label>
+                       <label index="list.checkConfig">Check configuration</label>
+                       <label index="list.checkConfig.ok.title">Configuration correct</label>
+                       <label index="list.checkConfig.ok.message">Connection is established and bind is successful.</label>
+                       <label index="list.checkConfig.failed.title">Configuration not correct</label>
+                       <label index="list.count">%d configuration(s)</label>
+               </languageKey>
+
+               <languageKey index="de" type="array">
+                       <label index="list">Übersicht</label>
+                       <label index="list.title">LDAP Konfigurationen</label>
+                       <label index="list.new">Konfiguration hinzufügen</label>
+                       <label index="list.edit">Konfiguration bearbeiten</label>
+                       <label index="list.checkConfig">Konfiguration prüfen</label>
+                       <label index="list.checkConfig.ok.title">Konfiguration korrekt</label>
+                       <label index="list.checkConfig.ok.message">Verbindung wurde hergestellt und Bind war erfolgreich.</label>
+                       <label index="list.checkConfig.failed.title">Konfiguration fehlerhaft</label>
+                       <label index="list.count">%d Konfiguration(en)</label>
+               </languageKey>
+       </data>
+</T3locallang>
diff --git a/Resources/Private/Language/locallang_db.xml b/Resources/Private/Language/locallang_db.xml
new file mode 100644 (file)
index 0000000..817f6ed
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+       <meta type="array">
+               <type>database</type>
+               <description>Language labels for database tables/fields belonging to extension 'ap_ldap'</description>
+       </meta>
+       <data type="array">
+               <languageKey index="default" type="array">
+                       <label index="tx_apldap_domain_model_config.title">LDAP Configuration</label>
+                       <label index="tx_apldap_domain_model_config.name">Name:</label>
+
+                       <label index="tx_apldap_domain_model_config.ldap_type">Server:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_type.I.0">OpenLDAP</label>
+                       <label index="tx_apldap_domain_model_config.ldap_type.I.1">Active Directory</label>
+                       <label index="tx_apldap_domain_model_config.ldap_protocol">Protocol:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_protocol.I.0">3</label>
+                       <label index="tx_apldap_domain_model_config.ldap_protocol.I.1">2</label>
+                       <label index="tx_apldap_domain_model_config.ldap_host">Host:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_port">Port:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_use_tls">Use TLS</label>
+                       <label index="tx_apldap_domain_model_config.ldap_bind_dn">Bind DN:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_password">Password:</label>
+
+                       <label index="tx_apldap_domain_model_config.tabs.general">General</label>
+                       <label index="tx_apldap_domain_model_config.tabs.server">LDAP Server</label>
+               </languageKey>
+
+               <languageKey index="de" type="array">
+                       <label index="tx_apldap_domain_model_config.title">LDAP Konfiguration</label>
+                       <label index="tx_apldap_domain_model_config.name">Name:</label>
+
+                       <label index="tx_apldap_domain_model_config.ldap_type">Server:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_type.I.0">OpenLDAP</label>
+                       <label index="tx_apldap_domain_model_config.ldap_type.I.1">Active Directory</label>
+                       <label index="tx_apldap_domain_model_config.ldap_protocol">Protokoll:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_protocol.I.0">3</label>
+                       <label index="tx_apldap_domain_model_config.ldap_protocol.I.1">2</label>
+                       <label index="tx_apldap_domain_model_config.ldap_host">Host:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_port">Port:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_use_tls">Benutze TLS</label>
+                       <label index="tx_apldap_domain_model_config.ldap_bind_dn">Bind DN:</label>
+                       <label index="tx_apldap_domain_model_config.ldap_password">Passwort:</label>
+
+                       <label index="tx_apldap_domain_model_config.tabs.general">Allgemein</label>
+                       <label index="tx_apldap_domain_model_config.tabs.server">LDAP Server</label>
+               </languageKey>
+       </data>
+</T3locallang>
diff --git a/Resources/Private/Language/locallang_mod.xml b/Resources/Private/Language/locallang_mod.xml
new file mode 100644 (file)
index 0000000..c349885
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+       <meta type="array">
+               <type>module</type>
+               <description>Language labels for module labels belonging to extension 'ap_ldap'</description>
+       </meta>
+       <data type="array">
+               <languageKey index="default" type="array">
+                       <label index="mlang_tabs_tab">LDAP</label>
+                       <label index="mlang_labels_tablabel"><![CDATA[]]></label>
+                       <label index="mlang_labels_tabdescr"><![CDATA[]]></label>
+               </languageKey>
+       </data>
+</T3locallang>
diff --git a/Resources/Private/Layouts/Default.html b/Resources/Private/Layouts/Default.html
new file mode 100644 (file)
index 0000000..167e6e2
--- /dev/null
@@ -0,0 +1,32 @@
+<f:be.container>
+       <div class="typo3-fullDoc">
+               <div id="typo3-docheader">
+                       <div class="typo3-docheader-functions">
+                               <div class="left">
+                                       <f:be.buttons.csh />
+                                       <f:be.menus.actionMenu>
+                                               <f:be.menus.actionMenuItem label="{f:translate(key: 'list')}" controller="LDAP" action="index" />
+                                       </f:be.menus.actionMenu>
+                               </div>
+                               <div class="right"></div>
+                       </div>
+                       <div class="typo3-docheader-buttons">
+                               <div class="left">
+                                       <f:render section="iconButtons" />
+                               </div>
+                               <div class="right">
+                                       <div class="buttongroup">
+                                               <f:be.buttons.icon uri="javascript: document.location.reload();" icon="actions-system-refresh" title="{f:translate(key: 'refresh')}" /><f:be.buttons.shortcut />
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+               <div id="typo3-docbody">
+                       <div id="typo3-inner-docbody">
+                               <f:flashMessages renderMode="div" />
+
+                               <f:render section="content" />
+                       </div>
+               </div>
+       </div>
+</f:be.container>
diff --git a/Resources/Private/Templates/LDAP/List.html b/Resources/Private/Templates/LDAP/List.html
new file mode 100644 (file)
index 0000000..203a1b0
--- /dev/null
@@ -0,0 +1,54 @@
+<f:layout name="default" />
+
+<f:section name="iconButtons">
+       <div class="buttongroup">
+               <f:be.buttons.icon uri="{f:uri.action(action: 'new')}" icon="actions-document-new" title="{f:translate(key: 'list.new')}" />
+       </div>
+</f:section>
+
+<f:section name="content">
+       <h3><f:translate key="list.title" /></h3>
+       <f:if condition="{f:count(subject: '{ldapConfigs}')} > 0">
+               <f:then>
+                       <table border="0" cellpadding="0" cellspacing="0" class="typo3-dblist">
+                               <tr class="t3-row-header">
+                                       <td></td>
+                                       <td>Name</td>
+                                       <td>Host</td>
+                                       <td>Port</td>
+                                       <td></td>
+                                       <td></td>
+                               </tr>
+                               <f:for each="{ldapConfigs}" as="ldapConfig">
+                                       <tr class="db_list_normal">
+                                               <td class="col-icon">
+                                                       <a href="#" onClick="showClickmenu('tx_apldap_domain_model_config', '{ldapConfig.uid}', '1', '', '', ''); return false;" title="id={ldapConfig.uid}">
+                                                               <f:image src="{f:uri.resource(path: 'Icons/ldap_configuration.png')}" alt="" title="" />
+                                                       </a>
+                                               </td>
+                                               <td><b>{ldapConfig.name}</b></td>
+                                               <td>{ldapConfig.ldapHost}</td>
+                                               <td><f:if condition="{ldapConfig.ldapPort}"><f:then>{ldapConfig.ldapPort}</f:then><f:else>-</f:else></f:if></td>
+                                               <td>
+                                                       <f:be.buttons.icon uri="{f:uri.action(action: 'checkConfig', arguments: {configUid: '{lpapConfig.uid}'})}" icon="apps-pagetree-folder-contains-approve" title="{f:translate(key: 'list.checkConfig')}" /> <f:link.action action="checkConfig" arguments="{configUid: '{ldapConfig.uid}'}"><f:translate key="list.checkConfig" /></f:link.action>
+                                               </td>
+                                               <td>
+                                                       <a href="#" onclick="top.launchView('tx_apldap_domain_model_config', '{ldapConfig.uid}'); return false;">
+                                                               <span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-info">&nbsp;</span>
+                                                       </a>
+                                                       <f:be.buttons.icon uri="{f:uri.action(action: 'edit', arguments: {configUid: '{ldapConfig.uid}'})}" icon="actions-document-open" title="{f:translate(key: 'list.edit')}" />
+                                               </td>
+                                       </tr>
+                               </f:for>
+                               <tr>
+                                       <td colspan="6">
+                                               <f:translate key="list.count" arguments="{0: '{f:count(subject: ldapConfigs)}'}" />
+                                       </td>
+                               </tr>
+                       </table>
+               </f:then>
+               <f:else>
+                       <f:render partial="message" arguments="{type: 'information', text: 'No configuration added." />
+               </f:else>
+       </f:if>
+</f:section>
diff --git a/Resources/Public/Icons/ldap_configuration.png b/Resources/Public/Icons/ldap_configuration.png
new file mode 100644 (file)
index 0000000..cfff027
Binary files /dev/null and b/Resources/Public/Icons/ldap_configuration.png differ
diff --git a/ext_conf_template.txt b/ext_conf_template.txt
new file mode 100644 (file)
index 0000000..50de3ae
--- /dev/null
@@ -0,0 +1,2 @@
+# cat=basic; type=int; label=Default configuration: Uid of the configuration record in table tx_apldap_domain_model_config.
+defaultConfigurationUid = 1
diff --git a/ext_emconf.php b/ext_emconf.php
new file mode 100644 (file)
index 0000000..dfaaae7
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Extension Manager/Repository config file for ext "ap_ldap".
+ *
+ * @var $_EXTKEY
+ */
+$EM_CONF[$_EXTKEY] = array(
+       'title' => 'LDAP',
+       'description' => 'Provides general configuration and core files for communication with LDAP servers.',
+       'author' => 'Alexander Pankow',
+       'author_email' => 'info@alexander-pankow.de',
+       'category' => 'services',
+       'author_company' => '',
+       'shy' => '',
+       'dependencies' => 'cms',
+       'conflicts' => '',
+       'priority' => '',
+       'module' => '',
+       'state' => 'alpha',
+       'internal' => '',
+       'uploadfolder' => 0,
+       'createDirs' => '',
+       'modify_tables' => '',
+       'clearCacheOnLoad' => 1,
+       'lockType' => '',
+       'version' => '0.0.1',
+       'constraints' => array(
+               'depends' => array(
+                       'typo3' => '6.1.1-6.1.99',
+                       'cms' => '',
+               ),
+               'conflicts' => array(),
+               'suggests' => array(),
+       ),
+       'suggests' => array(),
+       '_md5_values_when_last_written' => '',
+);
diff --git a/ext_icon.png b/ext_icon.png
new file mode 100644 (file)
index 0000000..cfff027
Binary files /dev/null and b/ext_icon.png differ
diff --git a/ext_tables.php b/ext_tables.php
new file mode 100644 (file)
index 0000000..fb202c0
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @var $_EXTKEY
+ */
+if (!defined ('TYPO3_MODE')) die ('Access denied.');
+
+// Register backend module
+if (TYPO3_MODE === 'BE') {
+       /**
+        * Registers a Backend Module
+        */
+       \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule(
+               'AP.' . $_EXTKEY,
+               'tools',
+               // Submodule key
+               'ldap',
+               // Position
+               'top',
+               // An array holding the controller-action-combinations that are accessible
+               array(
+                       'LDAP' => 'index, list, new, edit, checkConfig'
+               ),
+               array(
+                       'access' => 'user,group',
+                       'icon'   => 'EXT:' . $_EXTKEY . '/ext_icon.png',
+                       'labels' => 'LLL:EXT:' . $_EXTKEY . '/Resources/Private/Language/locallang_mod.xml',
+               )
+       );
+}
diff --git a/ext_tables.sql b/ext_tables.sql
new file mode 100644 (file)
index 0000000..133d018
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# Table structure for table 'tx_apldap_domain_model_config'
+#
+CREATE TABLE tx_apldap_domain_model_config (
+               uid int(11) NOT NULL auto_increment,
+               pid int(11) DEFAULT '0' NOT NULL,
+               tstamp int(11) DEFAULT '0' NOT NULL,
+               crdate int(11) DEFAULT '0' NOT NULL,
+               cruser_id int(11) DEFAULT '0' NOT NULL,
+               deleted tinyint(4) DEFAULT '0' NOT NULL,
+               hidden tinyint(4) DEFAULT '0' NOT NULL,
+               name varchar(255) DEFAULT '' NOT NULL,
+               ldap_type int(11) DEFAULT '0' NOT NULL,
+               ldap_protocol int(11) DEFAULT '0' NOT NULL,
+               ldap_host varchar(255) DEFAULT '' NOT NULL,
+               ldap_port int(11) DEFAULT '0' NOT NULL,
+               ldap_use_tls tinyint(1) DEFAULT '0' NOT NULL,
+               ldap_bind_dn tinytext NOT NULL,
+               ldap_password varchar(255) DEFAULT '' NOT NULL,
+               PRIMARY KEY (uid),
+               KEY parent (pid)
+);