-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d479d18
commit a06c783
Showing
27 changed files
with
906 additions
and
236 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
<?php | ||
|
||
require_once(__DIR__ . '/../web/inc/vars.inc.php'); | ||
if (file_exists(__DIR__ . '/../web/inc/vars.local.inc.php')) { | ||
include_once(__DIR__ . '/../web/inc/vars.local.inc.php'); | ||
} | ||
require_once __DIR__ . '/../web/inc/lib/vendor/autoload.php'; | ||
|
||
// Init database | ||
//$dsn = $database_type . ':host=' . $database_host . ';dbname=' . $database_name; | ||
$dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name; | ||
$opt = [ | ||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, | ||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, | ||
PDO::ATTR_EMULATE_PREPARES => false, | ||
]; | ||
try { | ||
$pdo = new PDO($dsn, $database_user, $database_pass, $opt); | ||
} | ||
catch (PDOException $e) { | ||
logMsg("err", $e->getMessage()); | ||
session_destroy(); | ||
exit; | ||
} | ||
|
||
// Init Redis | ||
$redis = new Redis(); | ||
try { | ||
if (!empty(getenv('REDIS_SLAVEOF_IP'))) { | ||
$redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT')); | ||
} | ||
else { | ||
$redis->connect('redis-mailcow', 6379); | ||
} | ||
} | ||
catch (Exception $e) { | ||
echo "Exiting: " . $e->getMessage(); | ||
session_destroy(); | ||
exit; | ||
} | ||
|
||
function logMsg($priority, $message, $task = "LDAP Sync") { | ||
global $redis; | ||
|
||
$finalMsg = array( | ||
"time" => time(), | ||
"priority" => $priority, | ||
"task" => $task, | ||
"message" => $message | ||
); | ||
$redis->lPush('CRON_LOG', json_encode($finalMsg)); | ||
} | ||
|
||
// Load core functions first | ||
require_once __DIR__ . '/../web/inc/functions.inc.php'; | ||
require_once __DIR__ . '/../web/inc/functions.auth.inc.php'; | ||
require_once __DIR__ . '/../web/inc/sessions.inc.php'; | ||
require_once __DIR__ . '/../web/inc/functions.mailbox.inc.php'; | ||
require_once __DIR__ . '/../web/inc/functions.ratelimit.inc.php'; | ||
require_once __DIR__ . '/../web/inc/functions.acl.inc.php'; | ||
|
||
$_SESSION['mailcow_cc_username'] = "admin"; | ||
$_SESSION['mailcow_cc_role'] = "admin"; | ||
$_SESSION['acl']['tls_policy'] = "1"; | ||
$_SESSION['acl']['quarantine_notification'] = "1"; | ||
$_SESSION['acl']['quarantine_category'] = "1"; | ||
$_SESSION['acl']['ratelimit'] = "1"; | ||
$_SESSION['acl']['sogo_access'] = "1"; | ||
$_SESSION['acl']['protocol_access'] = "1"; | ||
$_SESSION['acl']['mailbox_relayhost'] = "1"; | ||
$_SESSION['acl']['unlimited_quota'] = "1"; | ||
|
||
// Init Provider | ||
$iam_provider = identity_provider('init'); | ||
$iam_settings = identity_provider('get'); | ||
if ($iam_settings['authsource'] != "ldap" || (intval($iam_settings['periodic_sync']) != 1 && intval($iam_settings['import_users']) != 1)) { | ||
session_destroy(); | ||
exit; | ||
} | ||
|
||
// Set pagination variables | ||
$start = 0; | ||
$max = 25; | ||
|
||
// lock sync if already running | ||
$lock_file = '/tmp/iam-sync.lock'; | ||
if (file_exists($lock_file)) { | ||
$lock_file_parts = explode("\n", file_get_contents($lock_file)); | ||
$pid = $lock_file_parts[0]; | ||
if (count($lock_file_parts) > 1){ | ||
$last_execution = $lock_file_parts[1]; | ||
$elapsed_time = (time() - $last_execution) / 60; | ||
if ($elapsed_time < intval($iam_settings['sync_interval'])) { | ||
logMsg("warning", "Sync not ready (".number_format((float)$elapsed_time, 2, '.', '')."min / ".$iam_settings['sync_interval']."min)"); | ||
session_destroy(); | ||
exit; | ||
} | ||
} | ||
|
||
if (posix_kill($pid, 0)) { | ||
logMsg("warning", "Sync is already running"); | ||
session_destroy(); | ||
exit; | ||
} else { | ||
unlink($lock_file); | ||
} | ||
} | ||
$lock_file_handle = fopen($lock_file, 'w'); | ||
fwrite($lock_file_handle, getmypid()); | ||
fclose($lock_file_handle); | ||
|
||
// Get ldap users | ||
$response = $iam_provider->query() | ||
->where($iam_settings['username_field'], "*") | ||
->where($iam_settings['attribute_field'], "*") | ||
->select([$iam_settings['username_field'], $iam_settings['attribute_field'], 'displayname']) | ||
->paginate($max); | ||
|
||
// Process the users | ||
foreach ($response as $user) { | ||
$mailcow_template = $user[$iam_settings['attribute_field']][0]; | ||
|
||
// try get mailbox user | ||
$stmt = $pdo->prepare("SELECT `mailbox`.* FROM `mailbox` | ||
INNER JOIN domain on mailbox.domain = domain.domain | ||
WHERE `kind` NOT REGEXP 'location|thing|group' | ||
AND `domain`.`active`='1' | ||
AND `username` = :user"); | ||
$stmt->execute(array(':user' => $user[$iam_settings['username_field']][0])); | ||
$row = $stmt->fetch(PDO::FETCH_ASSOC); | ||
|
||
// check if matching attribute mapping exists | ||
$mbox_template = null; | ||
foreach ($iam_settings['mappers'] as $index => $mapper){ | ||
if ($mapper == $mailcow_template) { | ||
$mbox_template = $iam_settings['templates'][$index]; | ||
break; | ||
} | ||
} | ||
if (!$mbox_template){ | ||
logMsg("warning", "No matching attribute mapping found for user " . $user[$iam_settings['username_field']][0]); | ||
continue; | ||
} | ||
|
||
if (!$row && intval($iam_settings['import_users']) == 1){ | ||
// mailbox user does not exist, create... | ||
logMsg("info", "Creating user " . $user[$iam_settings['username_field']][0]); | ||
mailbox('add', 'mailbox_from_template', array( | ||
'domain' => explode('@', $user[$iam_settings['username_field']][0])[1], | ||
'local_part' => explode('@', $user[$iam_settings['username_field']][0])[0], | ||
'name' => $user['displayname'][0], | ||
'authsource' => 'ldap', | ||
'template' => $mbox_template | ||
)); | ||
} else if ($row && intval($iam_settings['periodic_sync']) == 1) { | ||
// mailbox user does exist, sync attribtues... | ||
logMsg("info", "Syncing attributes for user " . $user[$iam_settings['username_field']][0]); | ||
mailbox('edit', 'mailbox_from_template', array( | ||
'username' => $user[$iam_settings['username_field']][0], | ||
'name' => $user['displayname'][0], | ||
'template' => $mbox_template | ||
)); | ||
} else { | ||
// skip mailbox user | ||
logMsg("info", "Skipping user " . $user[$iam_settings['username_field']][0]); | ||
} | ||
|
||
sleep(0.025); | ||
} | ||
|
||
logMsg("info", "DONE!"); | ||
// add last execution time to lock file | ||
$lock_file_handle = fopen($lock_file, 'w'); | ||
fwrite($lock_file_handle, getmypid() . "\n" . time()); | ||
fclose($lock_file_handle); | ||
session_destroy(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,54 @@ | ||
// redirect to mailcow login form | ||
document.addEventListener('DOMContentLoaded', function () { | ||
var loginForm = document.forms.namedItem("loginForm"); | ||
if (loginForm) { | ||
window.location.href = '/'; | ||
} | ||
|
||
angularReady = false; | ||
// Wait for the Angular components to be initialized | ||
function waitForAngularComponents(callback) { | ||
const targetNode = document.body; | ||
|
||
const observer = new MutationObserver(function(mutations) { | ||
mutations.forEach(function(mutation) { | ||
if (mutation.addedNodes.length > 0) { | ||
const toolbarElement = document.body.querySelector('md-toolbar'); | ||
if (toolbarElement) { | ||
observer.disconnect(); | ||
callback(); | ||
} | ||
} | ||
}); | ||
}); | ||
|
||
const config = { childList: true, subtree: true }; | ||
observer.observe(targetNode, config); | ||
} | ||
|
||
// Usage | ||
waitForAngularComponents(function() { | ||
if (!angularReady){ | ||
angularReady = true; | ||
|
||
const toolbarElement = document.body.querySelector('.md-toolbar-tools.sg-toolbar-group-last.layout-align-end-center.layout-row'); | ||
|
||
var htmlCode = '<a class="md-icon-button md-button md-ink-ripple" aria-label="mailcow" href="/user" aria-hidden="false" tabindex="-1">' + | ||
'<md-icon class="material-icons" role="img" aria-label="build">build</md-icon>' + | ||
'</a><a class="md-icon-button md-button md-ink-ripple" aria-label="mailcow" href="#" onclick="logout.submit()" aria-hidden="false" tabindex="-1">' + | ||
'<md-icon class="material-icons" role="img" aria-label="settings_power">settings_power</md-icon>' + | ||
'</a><form action="/" method="post" id="logout"><input type="hidden" name="logout"></form>'; | ||
|
||
toolbarElement.insertAdjacentHTML('beforeend', htmlCode); | ||
} | ||
}); | ||
}); | ||
|
||
// Custom SOGo JS | ||
|
||
// Change the visible font-size in the editor, this does not change the font of a html message by default | ||
CKEDITOR.addCss("body {font-size: 16px !important}"); | ||
|
||
// Enable scayt by default | ||
//CKEDITOR.config.scayt_autoStartup = true; | ||
|
Oops, something went wrong.