View source
<?php
declare (strict_types=1);
namespace Drupal\ldap_user;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\ldap_servers\Entity\Server;
use Drupal\ldap_servers\LdapUserAttributesInterface;
use Drupal\ldap_servers\Mapping;
use Drupal\Core\Link;
use Drupal\Core\Url;
use function in_array;
class FieldProvider implements LdapUserAttributesInterface {
use StringTranslationTrait;
protected $config;
protected $entityTypeManager;
protected $moduleHandler;
protected $entityFieldManager;
private $server;
private $direction;
private $attributes = [];
public function __construct(ConfigFactory $config_factory, EntityTypeManagerInterface $entity_type_manager, ModuleHandler $module_handler, EntityFieldManager $entity_field_manager) {
$this->config = $config_factory
->get('ldap_user.settings');
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
$this->entityFieldManager = $entity_field_manager;
}
public function loadAttributes(string $direction, Server $server) : array {
$this->server = $server;
$this->direction = $direction;
if ($this->direction === self::PROVISION_TO_DRUPAL) {
$this
->addDn();
if ($this->server
->getUniquePersistentAttribute()) {
$this
->addPuidFields();
}
$triggers = $this->config
->get('drupalAcctProvisionTriggers');
if (!empty($triggers)) {
$this
->addBaseProperties();
}
}
if ($direction === self::PROVISION_TO_LDAP) {
$this
->addToLdapProvisioningFields();
}
$this
->addUserEntityFields();
$this
->exposeAvailableBaseFields();
$this
->loadUserDefinedMappings();
return $this->attributes;
}
private function loadUserDefinedMappings() : void {
$database_mappings = $this->config
->get('ldapUserSyncMappings');
if (!isset($database_mappings[$this->direction]) || empty($database_mappings[$this->direction])) {
return;
}
foreach ($database_mappings[$this->direction] as $id => $mapping) {
if (isset($this->attributes[$mapping['user_attr']])) {
$label = $this->attributes[$mapping['user_attr']]
->getLabel();
}
$prepared_mapping = new Mapping($id, $label ?? $id, TRUE, TRUE, $mapping['prov_events'], $mapping['config_module'], $mapping['prov_module']);
$prepared_mapping
->setDrupalAttribute($mapping['user_attr']);
$prepared_mapping
->setLdapAttribute($mapping['ldap_attr']);
$prepared_mapping
->setUserTokens($mapping['user_tokens']);
if ($mapping['convert']) {
$prepared_mapping
->convertBinary($mapping['convert']);
}
$key = $this->direction === self::PROVISION_TO_DRUPAL ? $mapping['user_attr'] : $mapping['ldap_attr'];
$this->attributes[$key] = $prepared_mapping;
}
}
public function attributeIsSyncedOnEvent(string $name, string $event) : bool {
if (isset($this->attributes[$name]) && $this->attributes[$name]
->isEnabled() && in_array($event, $this->attributes[$name]
->getProvisioningEvents(), TRUE)) {
return TRUE;
}
return FALSE;
}
public function getAttributesSyncedOnEvent(string $event) : array {
$synced_attributes = [];
foreach ($this->attributes as $key => $attribute) {
if ($attribute
->isEnabled() && in_array($event, $attribute
->getProvisioningEvents(), TRUE)) {
$synced_attributes[$key] = $attribute;
}
}
return $synced_attributes;
}
public function getConfigurableAttributesSyncedOnEvent(string $event) : array {
$synced_attributes = [];
foreach ($this->attributes as $key => $attribute) {
if ($attribute
->isEnabled() && $attribute
->isConfigurable() && in_array($event, $attribute
->getProvisioningEvents(), TRUE)) {
$synced_attributes[$key] = $attribute;
}
}
return $synced_attributes;
}
private function addPuidFields() : void {
$url = Url::fromRoute('entity.ldap_server.collection');
$url_string = $url
->toString(TRUE)
->getGeneratedUrl();
$tokens = [
'%edit_link' => Link::fromTextAndUrl($url_string, $url)
->toString(),
'%sid' => $this->server
->id(),
];
$fields = [
'[field.ldap_user_puid_sid]' => $this
->t('Field: sid providing PUID'),
'[field.ldap_user_puid]' => $this
->t('Field: PUID'),
'[field.ldap_user_puid_property]' => $this
->t('Field: PUID Attribute'),
];
foreach ($fields as $key => $name) {
$this->attributes[$key] = new Mapping($key, (string) $name, FALSE, TRUE, [
self::EVENT_CREATE_DRUPAL_USER,
], 'ldap_user', 'ldap_servers');
$this->attributes[$key]
->setNotes((string) $this
->t('configure at %edit_link', $tokens));
}
$this->attributes['[field.ldap_user_puid_sid]']
->setLdapAttribute($this->server
->id());
$this->attributes['[field.ldap_user_puid]']
->setLdapAttribute($this
->addTokens($this->server
->getUniquePersistentAttribute()));
$this->attributes['[field.ldap_user_puid_property]']
->setLdapAttribute($this->server
->getUniquePersistentAttribute());
}
private function addBaseProperties() : void {
$fields = [
'[property.name]' => 'Property: Username',
'[property.mail]' => 'Property: Email',
];
if ($this->server
->getPictureAttribute()) {
$fields['[property.picture]'] = 'Property: Picture';
}
foreach ($fields as $key => $name) {
$this->attributes[$key] = new Mapping($key, $name, FALSE, TRUE, [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
], 'ldap_servers', 'ldap_user');
}
$this->attributes['[property.name]']
->setLdapAttribute($this
->addTokens($this->server
->getAuthenticationNameAttribute()));
if ($this->server
->getMailTemplate()) {
$this->attributes['[property.mail]']
->setLdapAttribute($this->server
->getMailTemplate());
}
else {
$this->attributes['[property.mail]']
->setLdapAttribute($this
->addTokens($this->server
->getMailAttribute()));
}
if ($this->server
->getPictureAttribute()) {
$this->attributes['[property.picture]']
->setLdapAttribute($this
->addTokens($this->server
->getPictureAttribute()));
}
}
private function addTokens(string $input) : string {
return '[' . $input . ']';
}
private function addDn() : void {
$this->attributes['[field.ldap_user_current_dn]'] = new Mapping('[field.ldap_user_current_dn]', (string) $this
->t('Field: Most Recent DN'), FALSE, TRUE, [
self::EVENT_CREATE_DRUPAL_USER,
self::EVENT_SYNC_TO_DRUPAL_USER,
], 'ldap_user', 'ldap_servers');
$this->attributes['[field.ldap_user_current_dn]']
->setLdapAttribute('[dn]');
$this->attributes['[field.ldap_user_current_dn]']
->setNotes('not configurable');
}
private function addToLdapProvisioningFields() : void {
if (isset($this->attributes['[property.name]'])) {
$this->attributes['[property.name]']
->setConfigurationModule('ldap_user');
$this->attributes['[property.name]']
->setConfigurable(TRUE);
}
$fields = [
'[property.name]' => 'Property: Name',
'[property.mail]' => 'Property: Email',
'[property.picture]' => 'Property: Picture',
'[property.uid]' => 'Property: Drupal User Id (uid)',
'[password.random]' => 'Password: Random password',
'[password.user-random]' => 'Password: Plain user password or random',
'[password.user-only]' => 'Password: Plain user password',
];
foreach ($fields as $key => $name) {
if (isset($this->attributes[$key])) {
$this->attributes[$key]
->setConfigurationModule('ldap_user');
$this->attributes[$key]
->setConfigurable(TRUE);
}
else {
$this->attributes[$key] = new Mapping($key, $name, TRUE, FALSE, [
self::EVENT_CREATE_LDAP_ENTRY,
self::EVENT_SYNC_TO_LDAP_ENTRY,
], 'ldap_user', 'ldap_user');
}
}
}
private function exposeAvailableBaseFields() : void {
$this->server = $this->config
->get('drupalAcctProvisionServer');
$triggers = $this->config
->get('drupalAcctProvisionTriggers');
if ($this->server && !empty($triggers)) {
$fields = [
'[property.mail]',
'[property.name]',
'[property.picture]',
'[field.ldap_user_puid_sid]',
'[field.ldap_user_puid]',
];
foreach ($fields as $field) {
if (isset($this->attributes[$field])) {
$this->attributes[$field]
->setConfigurationModule('ldap_user');
}
}
}
}
private function addUserEntityFields() : void {
$this->attributes['[property.status]'] = new Mapping('[property.status]', 'Property: Account Status', TRUE, FALSE, [], 'ldap_user', 'ldap_user');
$this->attributes['[property.timezone]'] = new Mapping('[property.timezone]', 'Property: User Timezone', TRUE, FALSE, [], 'ldap_user', 'ldap_user');
$this->attributes['[property.signature]'] = new Mapping('[property.signature]', 'Property: User Signature', TRUE, FALSE, [], 'ldap_user', 'ldap_user');
$user_fields = $this->entityFieldManager
->getFieldStorageDefinitions('user');
foreach ($user_fields as $field_name => $field_instance) {
$field_id = sprintf('[field.%s]', $field_name);
if (!isset($this->attributes[$field_id])) {
$this->attributes[$field_id] = new Mapping($field_id, (string) $this
->t('Field: @label', [
'@label' => $field_instance
->getLabel(),
]), TRUE, FALSE, [], 'ldap_user', 'ldap_user');
}
}
}
}