mirror of
https://bitbucket.org/jsuto/piler.git
synced 2025-06-12 23:17:02 +02:00
added the webui to the tarball
This commit is contained in:
121
webui/model/audit/audit.php
Normal file
121
webui/model/audit/audit.php
Normal file
@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
class ModelAuditAudit extends Model {
|
||||
|
||||
public function search_audit($data = array()) {
|
||||
$where = '';
|
||||
$arr = $results = array();
|
||||
$from = 0;
|
||||
$sort = "ts";
|
||||
$order = "DESC";
|
||||
$sortorder = "ORDER BY ts DESC";
|
||||
$q = '';
|
||||
|
||||
|
||||
if($data['sort'] == "user") { $sort = "email"; }
|
||||
if($data['sort'] == "ipaddr") { $sort = "ipaddr"; }
|
||||
if($data['sort'] == "ref") { $sort = "meta_id"; }
|
||||
if($data['sort'] == "action") { $sort = "action"; }
|
||||
if($data['sort'] == "description") { $sort = "description"; }
|
||||
|
||||
if($data['order'] == 1) { $order = "ASC"; }
|
||||
|
||||
$sortorder = "ORDER BY `$sort` $order";
|
||||
|
||||
|
||||
if(isset($data['action']) && $data['action'] != ACTION_ALL) {
|
||||
$where .= " AND action=?";
|
||||
array_push($arr, $data['action']);
|
||||
}
|
||||
|
||||
if(isset($data['ipaddr'])) {
|
||||
$where .= " AND ipaddr IN (" . $this->append_search_criteria($data['ipaddr'], &$arr) . ")";
|
||||
}
|
||||
|
||||
if(isset($data['user'])) {
|
||||
$where .= " AND email IN (" . $this->append_search_criteria($data['user'], &$arr) . ")";
|
||||
}
|
||||
|
||||
if(isset($data['ref'])) {
|
||||
$where .= " AND ref IN (" . $this->append_search_criteria($data['ref'], &$arr) . ")";
|
||||
}
|
||||
|
||||
|
||||
$date = fixup_date_condition('ts', $data['date1'], $data['date2']);
|
||||
|
||||
|
||||
if($date) { $where .= " AND $date "; }
|
||||
|
||||
if($where) {
|
||||
$where = " WHERE " . substr($where, 5, strlen($where));
|
||||
}
|
||||
|
||||
$from = $data['page_len'] * $data['page'];
|
||||
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS count FROM " . TABLE_AUDIT . " $where", $arr);
|
||||
|
||||
$n = $query->row['count'];
|
||||
|
||||
if($n > 0) {
|
||||
if($n > MAX_AUDIT_HITS) { $n = MAX_AUDIT_HITS; }
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_AUDIT . " $where $sortorder LIMIT $from," . $data['page_len'], $arr);
|
||||
|
||||
|
||||
if(isset($query->rows)) {
|
||||
|
||||
foreach($query->rows as $a) {
|
||||
if($a['meta_id'] > 0) { $q .= "," . $a['meta_id']; }
|
||||
}
|
||||
|
||||
if($q) {
|
||||
$q = substr($q, 1, strlen($q));
|
||||
$Q = $this->db->query("SELECT id, piler_id FROM " . TABLE_META . " WHERE id IN($q)");
|
||||
|
||||
foreach($Q->rows as $a) {
|
||||
$m[$a['id']] = $a['piler_id'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach($query->rows as $a) {
|
||||
$results[] = array(
|
||||
'id' => $a['meta_id'],
|
||||
'piler_id' => isset($m[$a['meta_id']]) ? $m[$a['meta_id']] : '',
|
||||
'action' => $a['action'],
|
||||
'email' => $a['email'],
|
||||
'date' => date(AUDIT_DATE_FORMAT, $a['ts']),
|
||||
'ipaddr' => $a['ipaddr'],
|
||||
'description' => $a['description'],
|
||||
'shortdescription' => make_short_string($a['description'], MAX_CGI_FROM_SUBJ_LEN)
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array($n, $results);
|
||||
}
|
||||
|
||||
|
||||
private function append_search_criteria($s = '', $arr = array()) {
|
||||
$q = "";
|
||||
|
||||
$a = explode("*", $s);
|
||||
|
||||
for($i=0; $i<count($a); $i++) {
|
||||
if($a[$i]) {
|
||||
array_push($arr, $a[$i]);
|
||||
$q .= ",?";
|
||||
}
|
||||
}
|
||||
|
||||
$q = substr($q, 1, strlen($q));
|
||||
|
||||
return $q;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
47
webui/model/domain/domain.php
Normal file
47
webui/model/domain/domain.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
class ModelDomainDomain extends Model {
|
||||
|
||||
public function getDomains() {
|
||||
$query = $this->db->query("SELECT domain, mapped FROM " . TABLE_DOMAIN . " ORDER BY domain ASC");
|
||||
|
||||
return $query->rows;
|
||||
}
|
||||
|
||||
|
||||
public function deleteDomain($domain = '') {
|
||||
if($domain == "") { return 0; }
|
||||
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_DOMAIN . " WHERE domain=?", array($domain));
|
||||
|
||||
$rc = $this->db->countAffected();
|
||||
|
||||
LOGGER("remove domain: $domain (rc=$rc)");
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
public function addDomain($domain = '', $mapped = '') {
|
||||
if($domain == "" || $mapped == "") { return 0; }
|
||||
|
||||
$domains = explode("\n", $domain);
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
$domain = rtrim($domain);
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_DOMAIN . " (domain, mapped) VALUES (?,?)", array($domain, $mapped));
|
||||
|
||||
$rc = $this->db->countAffected();
|
||||
|
||||
LOGGER("add domain: $domain (rc=$rc)");
|
||||
|
||||
if($rc != 1){ return 0; }
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
114
webui/model/health/health.php
Normal file
114
webui/model/health/health.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
class ModelHealthHealth extends Model {
|
||||
|
||||
public function format_time($time = 0) {
|
||||
if($time >= 1) {
|
||||
return sprintf("%.2f", $time) . " sec";
|
||||
}
|
||||
else {
|
||||
return sprintf("%.2f", 1000*$time) . " ms";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function checksmtp($smtp = array(), $error = '') {
|
||||
|
||||
$ret = $error;
|
||||
$time = 0;
|
||||
|
||||
if($smtp[0] && $smtp[1] && is_numeric($smtp[1]) && $smtp[1] > 0 && $smtp[1] < 65536) {
|
||||
$time_start = microtime(true);
|
||||
|
||||
$s = @fsockopen($smtp[0], $smtp[1]);
|
||||
|
||||
if($s) {
|
||||
$ret = trim(fgets($s, 4096));
|
||||
fputs($s, "QUIT\r\n");
|
||||
fclose($s);
|
||||
}
|
||||
}
|
||||
|
||||
$time = microtime(true) - $time_start;
|
||||
return array($smtp[0] . ":" . $smtp[1], $ret, $this->format_time($time), $smtp[2]);
|
||||
}
|
||||
|
||||
|
||||
public function count_processed_emails() {
|
||||
$today = $last_7_days = $last_30_days = 0;
|
||||
$now = time();
|
||||
|
||||
$ts = $now - 86400;
|
||||
$query = $this->db->query("select count(*) as count from " . TABLE_META . " where arrived > $ts");
|
||||
if(isset($query->row['count'])) { $today = $query->row['count']; }
|
||||
|
||||
$ts = $now - 604800;
|
||||
$query = $this->db->query("select count(*) as count from " . TABLE_META . " where arrived > $ts");
|
||||
if(isset($query->row['count'])) { $last_7_days = $query->row['count']; }
|
||||
|
||||
$ts = $now - 2592000;
|
||||
$query = $this->db->query("select count(*) as count from " . TABLE_META . " where arrived > $ts");
|
||||
if(isset($query->row['count'])) { $last_30_days = $query->row['count']; }
|
||||
|
||||
return array($today, $last_7_days, $last_30_days);
|
||||
}
|
||||
|
||||
|
||||
public function uptime() {
|
||||
$s = exec("uptime");
|
||||
list ($uptime, $loadavg) = preg_split("/ load average\: /", $s);
|
||||
|
||||
return array(preg_replace("/\,\ {0,}$/", "", $uptime), $loadavg);
|
||||
}
|
||||
|
||||
|
||||
public function meminfo() {
|
||||
$m = explode("\n", file_get_contents("/proc/meminfo"));
|
||||
|
||||
while(list($k, $v) = each($m)) {
|
||||
$a = preg_split("/\ {1,}/", $v);
|
||||
if(isset($a[0]) && $a[0]) { $_m[$a[0]] = $a[1]; }
|
||||
}
|
||||
|
||||
$mem_percentage = sprintf("%.2f", 100*($_m['MemTotal:'] - $_m['MemFree:'] - $_m['Cached:']) / $_m['MemTotal:']);
|
||||
$swap_percentage = sprintf("%.2f", 100*($_m['SwapTotal:'] - $_m['SwapFree:']) / $_m['SwapTotal:']);
|
||||
|
||||
return array(sprintf("%.0f", $_m['MemTotal:'] / 1000), $mem_percentage, sprintf("%.0f", $_m['SwapTotal:'] / 1000), $swap_percentage);
|
||||
}
|
||||
|
||||
|
||||
public function diskinfo() {
|
||||
$shortinfo = array();
|
||||
|
||||
$s = exec("df -h", $output);
|
||||
|
||||
$partitions = Registry::get('partitions_to_monitor');
|
||||
|
||||
while(list($k, $v) = each($output)) {
|
||||
if($k > 0) {
|
||||
$p = preg_split("/\ {1,}/", $v);
|
||||
if(isset($p[5]) && in_array($p[5], $partitions)) {
|
||||
$shortinfo[] = array(
|
||||
'partition' => $p[5],
|
||||
'utilization' => preg_replace("/\%/", "", $p[4])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $shortinfo;
|
||||
}
|
||||
|
||||
|
||||
public function sysinfo() {
|
||||
$hostname = exec("hostname -f");
|
||||
$s = exec("uname -a");
|
||||
|
||||
return array($hostname, $s);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
51
webui/model/mail/mail.php
Normal file
51
webui/model/mail/mail.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
class ModelMailMail extends Model {
|
||||
|
||||
|
||||
public function send_smtp_email($smtphost, $smtpport, $yourdomain, $from, $to = array(), $msg){
|
||||
$ok = 0;
|
||||
|
||||
if($to == "" || strlen($msg) < 30){ return $ok; }
|
||||
|
||||
$r = fsockopen($smtphost, $smtpport);
|
||||
if(!$r){ return -1; }
|
||||
|
||||
$l = fgets($r, 4096);
|
||||
|
||||
fputs($r, "HELO $yourdomain\r\n");
|
||||
$l = fgets($r, 4096);
|
||||
|
||||
fputs($r, "MAIL FROM: <$from>\r\n");
|
||||
$l = fgets($r, 4096);
|
||||
|
||||
while(list($k, $v) = each($to)) {
|
||||
fputs($r, "RCPT TO: <$v>\r\n");
|
||||
$l = fgets($r, 4096);
|
||||
}
|
||||
|
||||
fputs($r, "DATA\r\n");
|
||||
$l = fgets($r, 4096);
|
||||
if(!preg_match("/^354/", $l)){ $l = fgets($r, 4096); }
|
||||
|
||||
fputs($r, $msg);
|
||||
|
||||
if(!preg_match("/\r\n.\r\n$/", $msg)){
|
||||
fputs($r, "\r\n.\r\n");
|
||||
}
|
||||
|
||||
$l = fgets($r, 4096);
|
||||
|
||||
if(preg_match("/^250/", $l)){ $ok = 1; }
|
||||
|
||||
fputs($r, "QUIT\r\n");
|
||||
$l = fgets($r, 4096);
|
||||
|
||||
fclose($r);
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
39
webui/model/policy/archiving.php
Normal file
39
webui/model/policy/archiving.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
|
||||
class ModelPolicyArchiving extends Model {
|
||||
|
||||
public function get_rules() {
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_ARCHIVING_RULE . " ORDER BY id");
|
||||
|
||||
if(isset($query->rows)) { return $query->rows; }
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
public function get_rule($id = 0) {
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_ARCHIVING_RULE . " WHERE id=?", array($id));
|
||||
|
||||
if(isset($query->row)) { return $query->row; }
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
public function add_new_rule($data = array()) {
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_ARCHIVING_RULE . " (`from`,`to`,`subject`,`_size`,`size`,`attachment_type`,`_attachment_size`,`attachment_size`) VALUES(?,?,?,?,?,?,?,?)", array($data['from'], $data['to'], $data['subject'], $data['_size'], $data['size'], $data['attachment_type'], $data['_attachment_size'], $data['attachment_size']));
|
||||
|
||||
return $this->db->countAffected();
|
||||
}
|
||||
|
||||
|
||||
public function remove_rule($id = 0) {
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_ARCHIVING_RULE . " WHERE id=?", array($id));
|
||||
return $this->db->countAffected();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
420
webui/model/search/message.php
Normal file
420
webui/model/search/message.php
Normal file
@ -0,0 +1,420 @@
|
||||
<?php
|
||||
|
||||
class ModelSearchMessage extends Model {
|
||||
|
||||
|
||||
public function get_store_path($id = '') {
|
||||
|
||||
if($id == '') { return ''; }
|
||||
|
||||
$len = strlen($id);
|
||||
|
||||
return DIR_STORE . "/" . substr($id, $len-6, 2) . "/" . substr($id, $len-4, 2) . "/" . substr($id, $len-2, 2) . "/" . $id;
|
||||
}
|
||||
|
||||
|
||||
public function verify_message($id = '') {
|
||||
if($id == '') { return 0; }
|
||||
|
||||
$q = $this->db->query("SELECT `size`, `hlen`, `digest`, `bodydigest`,`attachments` FROM " . TABLE_META . " WHERE piler_id=?", array($id));
|
||||
|
||||
$digest = $q->row['digest'];
|
||||
$bodydigest = $q->row['bodydigest'];
|
||||
$size = $q->row['size'];
|
||||
$hlen = $q->row['hlen'];
|
||||
$attachments = $q->row['attachments'];
|
||||
|
||||
$data = $this->get_raw_message($id);
|
||||
|
||||
$_digest = openssl_digest($data, "SHA256");
|
||||
$_bodydigest = openssl_digest(substr($data, $hlen), "SHA256");
|
||||
|
||||
$data = '';
|
||||
|
||||
if($_digest == $digest && $_bodydigest == $bodydigest) { return 1; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function get_raw_message($id = '') {
|
||||
$data = '';
|
||||
|
||||
if($id == '' || !preg_match("/^([0-9a-f]+)$/", $id)) { return $data; }
|
||||
|
||||
$handle = popen(DECRYPT_BINARY . " $id", "r");
|
||||
|
||||
while(($buf = fread($handle, DECRYPT_BUFFER_LENGTH))){
|
||||
$data .= $buf;
|
||||
}
|
||||
|
||||
pclose($handle);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function get_message_headers($id = '') {
|
||||
$data = '';
|
||||
|
||||
//$f = $this->get_store_path($id);
|
||||
//$msg = $this->decrypt_and_uncompress_file($f.".m");
|
||||
$msg = $this->get_raw_message($id);
|
||||
|
||||
$pos = strpos($msg, "\n\r\n");
|
||||
if($pos == false) {
|
||||
$pos = strpos($msg, "\n\n");
|
||||
}
|
||||
|
||||
if($pos == false) { return $msg; }
|
||||
|
||||
$data = substr($msg, 0, $pos);
|
||||
$msg = '';
|
||||
|
||||
$data = preg_replace("/\</", "<", $data);
|
||||
$data = preg_replace("/\>/", ">", $data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function extract_message($id = '') {
|
||||
$header = "";
|
||||
$body_chunk = "";
|
||||
$is_header = 1;
|
||||
$state = "UNDEF";
|
||||
$b = array();
|
||||
$boundary = array();
|
||||
$text_plain = 1;
|
||||
$text_html = 0;
|
||||
$charset = "";
|
||||
$qp = $base64 = 0;
|
||||
$has_text_plain = 0;
|
||||
|
||||
$from = $to = $subject = $date = $message = "";
|
||||
|
||||
$msg = $this->get_raw_message($id);
|
||||
|
||||
//print "a: $msg\n";
|
||||
|
||||
$a = explode("\n", $msg); $msg = "";
|
||||
|
||||
while(list($k, $l) = each($a)){
|
||||
$l .= "\n";
|
||||
|
||||
if(($l[0] == "\r" && $l[1] == "\n" && $is_header == 1) || ($l[0] == "\n" && $is_header == 1) ){
|
||||
$is_header = 0;
|
||||
}
|
||||
|
||||
if(preg_match("/^Content-Type:/i", $l)) $state = "CONTENT_TYPE";
|
||||
if(preg_match("/^Content-Transfer-Encoding:/i", $l)) $state = "CONTENT_TRANSFER_ENCODING";
|
||||
|
||||
if($state == "CONTENT_TYPE"){
|
||||
$x = strstr($l, "boundary");
|
||||
if($x){
|
||||
$x = preg_replace("/boundary =/", "boundary=", $x);
|
||||
$x = preg_replace("/boundary= /", "boundary=", $x);
|
||||
|
||||
$x = preg_replace("/\"/", "", $x);
|
||||
$x = preg_replace("/\'/", "", $x);
|
||||
|
||||
$b = explode("boundary=", $x);
|
||||
|
||||
array_push($boundary, rtrim($b[count($b)-1]));
|
||||
}
|
||||
|
||||
if(preg_match("/charset/i", $l)){
|
||||
$types = explode(";", $l);
|
||||
foreach ($types as $type){
|
||||
if(preg_match("/charset/i", $type)){
|
||||
$type = preg_replace("/[\"\'\ ]/", "", $type);
|
||||
|
||||
$x = explode("=", $type);
|
||||
$charset = $x[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(strstr($l, "text/plain")){ $text_plain = 1; $has_text_plain = 1; }
|
||||
if(strstr($l, "text/html")){ $text_html = 1; $text_plain = 0; }
|
||||
}
|
||||
|
||||
if($state == "CONTENT_TRANSFER_ENCODING"){
|
||||
if(strstr($l, "quoted-printable")){ $qp = 1; }
|
||||
if(strstr($l, "base64")){ $base64 = 1; }
|
||||
}
|
||||
|
||||
|
||||
if($is_header == 1){
|
||||
if($l[0] != " " && $l[0] != "\t"){ $state = "UNDEF"; }
|
||||
if(preg_match("/^From:/i", $l)){ $state = "FROM"; }
|
||||
if(preg_match("/^To:/i", $l) || preg_match("/^Cc:/i", $l)){ $state = "TO"; }
|
||||
if(preg_match("/^Date:/i", $l)){ $state = "DATE"; }
|
||||
if(preg_match("/^Subject:/i", $l)){ $state = "SUBJECT"; }
|
||||
if(preg_match("/^Content-Type:/", $l)){ $state = "CONTENT_TYPE"; }
|
||||
|
||||
$l = preg_replace("/</", "<", $l);
|
||||
$l = preg_replace("/>/", ">", $l);
|
||||
|
||||
if($state == "FROM"){ $from .= preg_replace("/\r|\n/", "", $l); }
|
||||
if($state == "TO"){ $to .= preg_replace("/\r|\n/", "", $l); }
|
||||
if($state == "SUBJECT"){ $subject .= preg_replace("/\r|\n/", "", $l); }
|
||||
if($state == "DATE"){ $date .= preg_replace("/\r|\n/", "", $l); }
|
||||
}
|
||||
else {
|
||||
|
||||
if($this->check_boundary($boundary, $l) == 1){
|
||||
|
||||
if($text_plain == 1 || $has_text_plain == 0) {
|
||||
$message .= $this->flush_body_chunk($body_chunk, $charset, $qp, $base64, $text_plain, $text_html);
|
||||
}
|
||||
|
||||
$text_plain = $text_html = $qp = $base64 = 0;
|
||||
|
||||
$charset = $body_chunk = "";
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
else if(($l[0] == "\r" && $l[1] == "\n") || $l[0] == "\n"){
|
||||
$state = "BODY";
|
||||
$body_chunk .= $l;
|
||||
}
|
||||
|
||||
else if($state == "BODY"){
|
||||
if($text_plain == 1 || $text_html == 1){ $body_chunk .= $l; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if($body_chunk && ($text_plain == 1 || $has_text_plain == 0) ){
|
||||
$message .= $this->flush_body_chunk($body_chunk, $charset, $qp, $base64, $text_plain, $text_html);
|
||||
}
|
||||
|
||||
|
||||
return array('from' => $this->decode_my_str($from),
|
||||
'to' => $this->decode_my_str($to),
|
||||
'subject' => $this->decode_my_str($subject),
|
||||
'date' => $this->decode_my_str($date),
|
||||
'message' => $message
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private function check_boundary($boundary, $line) {
|
||||
|
||||
for($i=0; $i<count($boundary); $i++){
|
||||
if(strstr($line, $boundary[$i])){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private function flush_body_chunk($chunk, $charset, $qp, $base64, $text_plain, $text_html) {
|
||||
|
||||
if($qp == 1){
|
||||
$chunk = $this->qp_decode($chunk);
|
||||
}
|
||||
|
||||
if($base64 == 1){
|
||||
$chunk = base64_decode($chunk);
|
||||
}
|
||||
|
||||
if(!preg_match("/utf-8/i", $charset)){
|
||||
$chunk = utf8_encode($chunk);
|
||||
}
|
||||
|
||||
if($text_plain == 1){
|
||||
$chunk = preg_replace("/</", "<", $chunk);
|
||||
$chunk = preg_replace("/>/", ">", $chunk);
|
||||
|
||||
//$chunk = "<pre>\n" . $this->print_nicely($chunk) . "</pre>\n";
|
||||
$chunk = preg_replace("/\n/", "<br />\n", $chunk);
|
||||
$chunk = "\n" . $this->print_nicely($chunk);
|
||||
}
|
||||
|
||||
if($text_html == 1){
|
||||
$chunk = preg_replace("/\<style([^\>]+)\>([\w\W]+)\<\/style\>/i", "", $chunk);
|
||||
|
||||
if(ENABLE_REMOTE_IMAGES == 0) {
|
||||
$chunk = preg_replace("/style([\s]{0,}=[\s]{0,})\"([^\"]+)/", "style=\"xxxx", $chunk);
|
||||
$chunk = preg_replace("/style([\s]{0,}=[\s]{0,})\'([^\']+)/", "style=\'xxxx", $chunk);
|
||||
}
|
||||
|
||||
$chunk = preg_replace("/\<body ([\w\s\;\"\'\#\d\:\-\=]+)\>/i", "<body>", $chunk);
|
||||
|
||||
if(ENABLE_REMOTE_IMAGES == 0) { $chunk = preg_replace("/\<img([^\>]+)\>/i", "<img src=\"" . REMOTE_IMAGE_REPLACEMENT . "\" />", $chunk); }
|
||||
|
||||
/* prevent scripts in the HTML part */
|
||||
|
||||
$chunk = preg_replace("/document\.write/", "document.writeee", $chunk);
|
||||
$chunk = preg_replace("/<\s{0,}script([\w\W]+)\/script\s{0,}\>/i", "<!-- disabled javascript here -->", $chunk);
|
||||
}
|
||||
|
||||
return $chunk;
|
||||
}
|
||||
|
||||
|
||||
private function print_nicely($chunk) {
|
||||
$k = 0;
|
||||
$nice_chunk = "";
|
||||
|
||||
$x = explode(" ", $chunk);
|
||||
|
||||
for($i=0; $i<count($x); $i++){
|
||||
$nice_chunk .= "$x[$i] ";
|
||||
$k += strlen($x[$i]);
|
||||
|
||||
if(strstr($x[$i], "\n")){ $k = 0; }
|
||||
|
||||
if($k > 70){ $nice_chunk .= "\n"; $k = 0; }
|
||||
}
|
||||
|
||||
return $nice_chunk;
|
||||
}
|
||||
|
||||
|
||||
public function NiceSize($size) {
|
||||
if($size < 1000) return "1k";
|
||||
if($size < 100000) return round($size/1000) . "k";
|
||||
|
||||
return sprintf("%.1f", $size/1000000) . "M";
|
||||
}
|
||||
|
||||
|
||||
private function qp_decode($l) {
|
||||
$res = "";
|
||||
$c = "";
|
||||
|
||||
if($l == ""){ return ""; }
|
||||
|
||||
/* remove soft breaks at the end of lines */
|
||||
|
||||
if(preg_match("/\=\r\n/", $l)){ $l = preg_replace("/\=\r\n/", "", $l); }
|
||||
if(preg_match("/\=\n/", $l)){ $l = preg_replace("/\=\n/", "", $l); }
|
||||
|
||||
for($i=0; $i<strlen($l); $i++){
|
||||
$c = $l[$i];
|
||||
|
||||
if($c == '=' && ctype_xdigit($l[$i+1]) && ctype_xdigit($l[$i+2])){
|
||||
$a = $l[$i+1];
|
||||
$b = $l[$i+2];
|
||||
|
||||
$c = chr(16*hexdec($a) + hexdec($b));
|
||||
|
||||
$i += 2;
|
||||
}
|
||||
|
||||
$res .= $c;
|
||||
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
public function decode_my_str($what = '') {
|
||||
$result = "";
|
||||
|
||||
$what = rtrim($what);
|
||||
|
||||
$a = preg_split("/\s/", $what);
|
||||
|
||||
while(list($k, $v) = each($a)){
|
||||
$x = preg_match("/\?\=$/", $v);
|
||||
|
||||
if( ($x == 0 && $k > 0) || ($x == 1 && $k == 1) ){
|
||||
$result .= " ";
|
||||
}
|
||||
|
||||
$result .= $this->fix_encoded_string($v);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
private function fix_encoded_string($what = '') {
|
||||
$s = "";
|
||||
|
||||
$what = rtrim($what, "\"\r\n");
|
||||
$what = ltrim($what, "\"");
|
||||
|
||||
if(preg_match("/^\=\?/", $what) && preg_match("/\?\=$/", $what)){
|
||||
$what = preg_replace("/^\=\?/", "", $what);
|
||||
$what = preg_replace("/\?\=$/", "", $what);
|
||||
|
||||
if(preg_match("/\?Q\?/i", $what)){
|
||||
$x = preg_replace("/^([\w\-]+)\?Q\?/i", "", $what);
|
||||
|
||||
$s = quoted_printable_decode($x);
|
||||
$s = preg_replace("/_/", " ", $s);
|
||||
}
|
||||
|
||||
if(preg_match("/\?B\?/i", $what)){
|
||||
$x = preg_replace("/^([\w\-]+)\?B\?/i", "", $what);
|
||||
|
||||
$s = base64_decode($x);
|
||||
$s = preg_replace('/\0/', "*", $s);
|
||||
}
|
||||
|
||||
|
||||
if(!preg_match("/utf-8/i", $what)){
|
||||
$s = utf8_encode($s);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$s = utf8_encode($what);
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
public function get_message_tag($id = '', $uid = 0) {
|
||||
if($id == '' || $uid <= 0) { return ''; }
|
||||
|
||||
$query = $this->db->query("SELECT `tag` FROM " . TABLE_TAG . "," . TABLE_META . " WHERE " . TABLE_TAG . ".id=" . TABLE_META . ".id AND uid=? AND piler_id=?", array($uid, $id));
|
||||
|
||||
if(isset($query->row['tag'])) { return $query->row['tag']; }
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
public function add_message_tag($id = '', $uid = 0, $tag = '') {
|
||||
if($id == '' || $uid <= 0) { return 0; }
|
||||
|
||||
$query = $this->db->query("SELECT `id` FROM " . TABLE_META . " WHERE piler_id=?", array($id));
|
||||
|
||||
if(isset($query->row['id']) && $query->row['id'] > 0) {
|
||||
|
||||
$id = $query->row['id'];
|
||||
|
||||
if($tag == '') {
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_TAG . " WHERE uid=? AND id=?", array($uid, $id));
|
||||
} else {
|
||||
$query = $this->db->query("UPDATE " . TABLE_TAG . " SET tag=? WHERE uid=? AND id=?", array($tag, $uid, $id));
|
||||
if($this->db->countAffected() == 0) {
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_TAG . " (id, uid, tag) VALUES(?,?,?)", array($id, $uid, $tag));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
502
webui/model/search/search.php
Normal file
502
webui/model/search/search.php
Normal file
@ -0,0 +1,502 @@
|
||||
<?php
|
||||
|
||||
class ModelSearchSearch extends Model {
|
||||
|
||||
public function search_messages($data = array(), $search_type = SIMPLE_SEARCH, $page = 0) {
|
||||
$one_page_of_ids = array();
|
||||
$total_hits = 0;
|
||||
$sort = "sent";
|
||||
$order = "DESC";
|
||||
$sortorder = "ORDER BY sent DESC";
|
||||
$cache_key = "";
|
||||
$q = "";
|
||||
$s = "";
|
||||
|
||||
while(list($k,$v) = each($data)) {
|
||||
if($v) { $s .= '&' . $k . '=' . $v; }
|
||||
}
|
||||
|
||||
if($s) { $s = substr($s, 1, strlen($s)); }
|
||||
|
||||
AUDIT(ACTION_SEARCH, '', '', 0, $s);
|
||||
|
||||
|
||||
if($data['sort'] == "sent") { $sort = "sent"; }
|
||||
if($data['sort'] == "size") { $sort = "size"; }
|
||||
if($data['sort'] == "from") { $sort = "from"; }
|
||||
if($data['sort'] == "subj") { $sort = "subject"; }
|
||||
|
||||
if($data['order'] == 1) { $order = "ASC"; }
|
||||
|
||||
$sortorder = "ORDER BY `$sort` $order";
|
||||
|
||||
$m = array();
|
||||
|
||||
if(MEMCACHED_ENABLED) {
|
||||
$cache_key = $this->make_cache_file_name($data, $sortorder);
|
||||
$memcache = Registry::get('memcache');
|
||||
$m = $memcache->get($cache_key);
|
||||
}
|
||||
|
||||
|
||||
if(isset($m['ids'])) {
|
||||
$all_ids = $m['ids'];
|
||||
} else {
|
||||
|
||||
if($search_type == SIMPLE_SEARCH) {
|
||||
$conditions = $this->assemble_simple_query_conditions($data);
|
||||
}
|
||||
else {
|
||||
$conditions = $this->assemble_advanced_query_conditions($data);
|
||||
}
|
||||
|
||||
$all_ids = $this->query_all_possible_IDs($data, $conditions, $sort, $order, $sortorder, $cache_key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$total_hits = count($all_ids);
|
||||
|
||||
$data['page_len'] = get_page_length();
|
||||
|
||||
if($total_hits > 0) {
|
||||
$i = 0;
|
||||
|
||||
foreach($all_ids as $id) {
|
||||
|
||||
if($i >= $data['page_len'] * $page && $i < $data['page_len'] * ($page+1) ) {
|
||||
array_push($one_page_of_ids, $id);
|
||||
|
||||
if($q) { $q .= ",?"; } else { $q = "?"; }
|
||||
}
|
||||
|
||||
$i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return array($total_hits, $this->get_meta_data($one_page_of_ids, $q, $sortorder));
|
||||
}
|
||||
|
||||
|
||||
private function assemble_advanced_query_conditions($data = array()) {
|
||||
$f1 = $f2 = $t1 = $t2 = $fd = $td = '';
|
||||
$incoming = $outgoing = '';
|
||||
$email = $match = '';
|
||||
$n_fc = $n_tc = 0;
|
||||
|
||||
|
||||
$data['f_from'] = $this->fix_email_address_for_sphinx($data['f_from']);
|
||||
$data['o_from'] = $this->fix_email_address_for_sphinx($data['o_from']);
|
||||
$data['f_to'] = $this->fix_email_address_for_sphinx($data['f_to']);
|
||||
$data['o_to'] = $this->fix_email_address_for_sphinx($data['o_to']);
|
||||
$data['from_domain'] = $this->fix_email_address_for_sphinx($data['from_domain']);
|
||||
$data['to_domain'] = $this->fix_email_address_for_sphinx($data['to_domain']);
|
||||
|
||||
$data['body'] = $this->fixup_sphinx_operators($data['body']);
|
||||
$data['subject'] = $this->fixup_sphinx_operators($data['subject']);
|
||||
|
||||
|
||||
if(Registry::get('admin_user') == 1 || Registry::get('auditor_user') == 1) {
|
||||
if($data['f_from']) { $f1 .= "|" . $data['f_from']; $n_fc++; }
|
||||
if($data['o_from']) { $f1 .= "|" . $data['o_from']; $n_fc++; }
|
||||
if($data['from_domain']) { $fd .= "(@fromdomain " . $data['from_domain'] . ")"; $n_fc++; }
|
||||
|
||||
if($data['f_to']) { $t1 .= "|" . $data['f_to']; $n_tc++; }
|
||||
if($data['o_to']) { $t1 .= "|" . $data['o_to']; $n_tc++; }
|
||||
if($data['to_domain']) { $td .= "(@todomain " . $data['to_domain'] . ")"; $n_tc++; }
|
||||
|
||||
if($f1) { $f1 = "(@from " . substr($f1, 1, strlen($f1)) . ")"; }
|
||||
if($t1) { $t1 = "(@to " . substr($t1, 1, strlen($t1)) . ")"; }
|
||||
|
||||
}
|
||||
else {
|
||||
$all_your_addresses = $this->get_all_your_address();
|
||||
|
||||
if($data['f_from']) { $f1 = "(@from " . $data['f_from'] . " @to $all_your_addresses)"; $n_fc++; }
|
||||
if($data['o_from']) { $f2 = "(@from " . $data['o_from'] . ")"; $n_fc++; }
|
||||
if($data['from_domain']) { $fd = "(@fromdomain " . $data['from_domain'] . " @to $all_your_addresses)"; $n_fc++; }
|
||||
|
||||
if($data['f_to']) { $t1 = "(@to " . $data['f_to'] . " @from $all_your_addresses)"; $n_tc++; }
|
||||
if($data['o_to']) { $t2 = "(@to " . $data['o_to'] . ")"; $n_tc++; }
|
||||
if($data['to_domain']) { $td = "(@todomain " . $data['to_domain'] . " @from $all_your_addresses)"; $n_tc++; }
|
||||
|
||||
if($n_fc == 0 && $n_tc == 0 && $data['from_domain'] == '' && $data['to_domain'] == '') {
|
||||
if($data['direction'] == 2) {
|
||||
$f1 = " (@from " . $all_your_addresses . ")";
|
||||
} else {
|
||||
$t1 = " (@to " . $all_your_addresses . ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($f1) { $incoming .= "|$f1"; }
|
||||
if($f2) { $incoming .= "|$f2"; }
|
||||
if($fd) { $incoming .= "|$fd"; }
|
||||
|
||||
if($t1) { $outgoing .= "|$t1"; }
|
||||
if($t2) { $outgoing .= "|$t2"; }
|
||||
if($td) { $outgoing .= "|$td"; }
|
||||
|
||||
if($incoming) { $incoming = substr($incoming, 1, strlen($incoming)); if($n_fc > 1) { $incoming = "($incoming)"; } }
|
||||
if($outgoing) { $outgoing = substr($outgoing, 1, strlen($outgoing)); if($n_tc > 1) { $outgoing = "($outgoing)"; } }
|
||||
|
||||
|
||||
if($incoming) {
|
||||
$email = $incoming;
|
||||
if($outgoing) { $email = $incoming . " & " . $outgoing; }
|
||||
} else if($outgoing) {
|
||||
$email = $outgoing;
|
||||
}
|
||||
|
||||
|
||||
if($email) { $match = $email; }
|
||||
|
||||
if($data['body']) { if($match) { $match .= " & "; } $match .= "(@body " . $data['body'] . ") "; }
|
||||
if($data['subject']) { if($match) { $match .= " & "; } $match .= "(@subject " . $data['subject'] . ") "; }
|
||||
if($data['attachment_type']) { if($match) { $match .= " & "; } $match .= "(@attachment_types " . $data['attachment_type'] . ") "; }
|
||||
|
||||
return $match;
|
||||
}
|
||||
|
||||
|
||||
private function assemble_simple_query_conditions($data = array(), $sort = 'sent', $order = 'DESC', $sortorder = '', $cache_key = '') {
|
||||
$email = $match = "";
|
||||
|
||||
if(Registry::get('admin_user') == 0 && Registry::get('auditor_user') == 0) {
|
||||
|
||||
$all_your_addresses = $this->get_all_your_address();
|
||||
|
||||
if(isset($data['from'])) { $data['from'] = fix_email_address($data['from']); }
|
||||
if(isset($data['to'])) { $data['to'] = fix_email_address($data['to']); }
|
||||
|
||||
// missing from address
|
||||
|
||||
if(!isset($data['from'])) {
|
||||
|
||||
if(isset($data['to']) && !strstr($data['to'], '@')) { $email = "@from $all_your_addresses @todomain " . $this->fix_email_address_for_sphinx($data['to']); }
|
||||
else if(!isset($data['to'])) { $email = "@to $all_your_addresses"; }
|
||||
else if(!in_array($data['to'], $_SESSION['emails'])) { $email = "@from $all_your_addresses @to " . $this->fix_email_address_for_sphinx($data['to']); }
|
||||
else { $email = "@to " . $this->fix_email_address_for_sphinx($data['to']); }
|
||||
|
||||
}
|
||||
|
||||
// missing to address
|
||||
|
||||
else if(!isset($data['to'])) {
|
||||
if(isset($data['from']) && !strstr($data['from'], '@')) { $email = "@to $all_your_addresses @fromdomain " . $this->fix_email_address_for_sphinx($data['from']); }
|
||||
else if(!in_array($data['from'], $_SESSION['emails'])) { $email = "@to $all_your_addresses @from " . $this->fix_email_address_for_sphinx($data['from']); }
|
||||
else { $email = "@from " . $this->fix_email_address_for_sphinx($data['from']); }
|
||||
}
|
||||
|
||||
else if(isset($data['from']) && isset($data['to'])) {
|
||||
|
||||
if(
|
||||
(!in_array($data['from'], $_SESSION['emails']) && in_array($data['to'], $_SESSION['emails'])) ||
|
||||
(!in_array($data['to'], $_SESSION['emails']) && in_array($data['from'], $_SESSION['emails']))
|
||||
) {
|
||||
$email = "@from " . $this->fix_email_address_for_sphinx($data['from']) . " @to " . $this->fix_email_address_for_sphinx($data['to']);
|
||||
}
|
||||
|
||||
else {
|
||||
$email = " @to INVALID ";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
if(isset($data['from'])) {
|
||||
if(strstr($data['from'], '@')) { $match .= " @from " . $this->fix_email_address_for_sphinx($data['from']); }
|
||||
else { $match .= " @fromdomain " . $this->fix_email_address_for_sphinx($data['from']); }
|
||||
}
|
||||
|
||||
if(isset($data['to'])) {
|
||||
if(strstr($data['to'], '@')) { $match .= " @to " . $this->fix_email_address_for_sphinx($data['to']); }
|
||||
else { $match .= " @todomain " . $this->fix_email_address_for_sphinx($data['to']); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(isset($data['subject'])) {
|
||||
$data['subject'] = $this->fixup_sphinx_operators($data['subject']);
|
||||
$match .= " @(subject,body) " . $data['subject'];
|
||||
}
|
||||
|
||||
|
||||
if($email) { $match = " $email " . $match; }
|
||||
|
||||
return $match;
|
||||
}
|
||||
|
||||
|
||||
private function query_all_possible_IDs($data = array(), $conditions = '', $sort = 'sent', $order = 'DESC', $sortorder = '', $cache_key = '') {
|
||||
$ids = array();
|
||||
$direction = $size = '';
|
||||
$tag_id_list = '';
|
||||
|
||||
|
||||
if($data['sort'] == 'from' || $data['sort'] == 'subj') { $sortorder = ''; }
|
||||
|
||||
$date = fixup_date_condition('sent', $data['date1'], $data['date2']);
|
||||
|
||||
if($date) { $date .= " AND "; }
|
||||
|
||||
if(isset($data['direction']) && $data['direction'] != '') { $direction = "direction = " . $data['direction'] . " AND "; }
|
||||
|
||||
if(isset($data['size']) && $data['size']) {
|
||||
$data['size'] = preg_replace("/\s/", "", $data['size']);
|
||||
if(preg_match("/^(\>|\<)\={0,}\d{1,}$/", $data['size'])) { $size = "size " . $data['size'] . " AND "; }
|
||||
}
|
||||
|
||||
|
||||
if($data['tag']) {
|
||||
$tag_id_list = " AND id IN (0";
|
||||
|
||||
$data['tag'] = $this->fixup_sphinx_operators($data['tag']);
|
||||
|
||||
$aa = $this->sphx->query("SELECT id FROM " . SPHINX_TAG_INDEX . " WHERE uid=" . $_SESSION['uid'] . " AND MATCH('@tag " . $data['tag'] . " ') ");
|
||||
|
||||
foreach($aa->rows as $a) {
|
||||
$tag_id_list .= "," . $a['id'];
|
||||
}
|
||||
|
||||
$tag_id_list .= ") ";
|
||||
}
|
||||
|
||||
|
||||
|
||||
$query = $this->sphx->query("SELECT id FROM " . SPHINX_MAIN_INDEX . " WHERE $date $direction $size MATCH('$conditions') $tag_id_list $sortorder LIMIT 0," . MAX_SEARCH_HITS);
|
||||
|
||||
//print $query->query; print "<p>" . $query->exec_time . "</p>\n";
|
||||
|
||||
|
||||
/*
|
||||
* build an id list
|
||||
*/
|
||||
|
||||
$q = "";
|
||||
|
||||
foreach($query->rows as $a) {
|
||||
array_push($ids, $a['id']);
|
||||
|
||||
if($q) { $q .= ",?"; }
|
||||
else { $q = "?"; }
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* if the query was requested to be sorted by sender or subject, then sphinx cannot do
|
||||
* that, so we assemble the list of all sphinx IDs matching the query
|
||||
*/
|
||||
|
||||
if($data['sort'] == 'from' || $data['sort'] == 'subj') {
|
||||
|
||||
$query = $this->db->query("SELECT id FROM " . TABLE_META . " WHERE id IN ($q) ORDER BY `$sort` $order", $ids);
|
||||
//print $query->query . ", exec: " . $query->exec_time . "<p/>\n";
|
||||
|
||||
$ids = array();
|
||||
|
||||
foreach($query->rows as $q) {
|
||||
array_push($ids, $q['id']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(MEMCACHED_ENABLED && $cache_key) {
|
||||
$memcache = Registry::get('memcache');
|
||||
$memcache->add($cache_key, array('ts' => time(), 'total_hits' => count($ids), 'ids' => $ids), 0, MEMCACHED_TTL);
|
||||
}
|
||||
|
||||
|
||||
return $ids;
|
||||
}
|
||||
|
||||
|
||||
private function get_meta_data($ids = array(), $q = '', $sortorder = '') {
|
||||
$messages = array();
|
||||
$tag = array();
|
||||
|
||||
|
||||
if(count($ids) == 0) return $messages;
|
||||
|
||||
$query = $this->db->query("SELECT `id`, `from`, `subject`, `piler_id`, `reference`, `size`, `spam`, `sent`, `arrived`, `attachments` FROM `" . TABLE_META . "` WHERE `id` IN ($q) $sortorder", $ids);
|
||||
|
||||
|
||||
if(isset($query->rows)) {
|
||||
|
||||
$tags = $this->db->query("SELECT `id`, `tag` FROM `" . TABLE_TAG . "` WHERE `id` IN ($q)", $ids);
|
||||
foreach ($tags->rows as $t) {
|
||||
$tag[$t['id']] = $t['tag'];
|
||||
}
|
||||
|
||||
|
||||
$lang = Registry::get('language');
|
||||
|
||||
foreach($query->rows as $m) {
|
||||
$m['shortfrom'] = make_short_string($m['from'], MAX_CGI_FROM_SUBJ_LEN);
|
||||
|
||||
if($m['subject'] == "") { $m['subject'] = "<" . $lang->data['text_no_subject'] . ">"; }
|
||||
|
||||
$m['subject'] = escape_gt_lt_quote_symbols($m['subject']);
|
||||
$m['shortsubject'] = make_short_string($m['subject'], MAX_CGI_FROM_SUBJ_LEN);
|
||||
|
||||
$m['date'] = date(SEARCH_HIT_DATE_FORMAT, $m['sent']);
|
||||
$m['size'] = nice_size($m['size']);
|
||||
|
||||
|
||||
/*
|
||||
* verifying 20 messages takes some time, still it's useful
|
||||
*/
|
||||
|
||||
if(ENABLE_ON_THE_FLY_VERIFICATION == 1) {
|
||||
$m['verification'] = $this->model_search_message->verify_message($m['piler_id']);
|
||||
}
|
||||
|
||||
if(isset($tag[$m['id']])) { $m['tag'] = $tag[$m['id']]; } else { $m['tag'] = ''; }
|
||||
|
||||
array_push($messages, $m);
|
||||
}
|
||||
}
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
|
||||
public function get_message_recipients($id = '') {
|
||||
$rcpt = array();
|
||||
|
||||
if(Registry::get('admin_user') == 0 && Registry::get('auditor_user') == 0) { return $rcpt; }
|
||||
|
||||
$query = $this->db->query("SELECT `to` FROM " . VIEW_MESSAGES . " WHERE piler_id=?", array($id));
|
||||
|
||||
foreach($query->rows as $q) {
|
||||
array_push($rcpt, $q['to']);
|
||||
}
|
||||
|
||||
return $rcpt;
|
||||
}
|
||||
|
||||
|
||||
private function get_all_your_address() {
|
||||
$s = '';
|
||||
|
||||
while(list($k, $v) = each($_SESSION['emails'])) {
|
||||
if($s) { $s .= '| ' . $this->fix_email_address_for_sphinx($v); }
|
||||
else { $s = $this->fix_email_address_for_sphinx($v); }
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
public function check_your_permission_by_piler_id($id = '') {
|
||||
$q = '';
|
||||
$arr = $a = array();
|
||||
|
||||
if($id == '') { return 0; }
|
||||
|
||||
if(Registry::get('admin_user') == 1 || Registry::get('auditor_user') == 1) { return 1; }
|
||||
|
||||
array_push($arr, $id);
|
||||
|
||||
while(list($k, $v) = each($_SESSION['emails'])) {
|
||||
if(validemail($v) == 1) {
|
||||
$q .= ",?";
|
||||
array_push($a, $v);
|
||||
}
|
||||
}
|
||||
|
||||
$q = preg_replace("/^\,/", "", $q);
|
||||
|
||||
$arr = array_merge($arr, $a, $a);
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . VIEW_MESSAGES . " WHERE piler_id=? AND ( `from` IN ($q) OR `to` IN ($q) )", $arr);
|
||||
|
||||
if(isset($query->row['id'])) { return 1; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function remove_message($id = '') {
|
||||
if($id == '') { return 0; }
|
||||
|
||||
if(Registry::get('admin_user') == 0) { return 0; }
|
||||
|
||||
$query = $this->db->query("UPDATE " . TABLE_META . " SET deleted=1 WHERE piler_id=?", array($id));
|
||||
|
||||
return $this->db->countAffected();
|
||||
}
|
||||
|
||||
|
||||
private function fix_email_address_for_sphinx($email = '') {
|
||||
return preg_replace("/[\@\.\+\-]/", "X", $email);
|
||||
}
|
||||
|
||||
|
||||
public function get_search_terms() {
|
||||
|
||||
$query = $this->db->query("SELECT term FROM " . TABLE_SEARCH . " where email=? ORDER BY ts DESC", array($_SESSION['email']));
|
||||
if(isset($query->rows)) { return $query->rows; }
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
public function add_search_term($term = '') {
|
||||
if($term == '') { return 0; }
|
||||
|
||||
if($this->update_search_term($term) == 0) {
|
||||
AUDIT(ACTION_SAVE_SEARCH, '', '', '', $term);
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_SEARCH . " (email, ts, term) VALUES(?,?,?)", array($_SESSION['email'], time(), $term));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function update_search_term($term = '') {
|
||||
if($term == '') { return 0; }
|
||||
|
||||
AUDIT(ACTION_SEARCH, '', '', '', $term);
|
||||
|
||||
$query = $this->db->query("UPDATE " . TABLE_SEARCH . " SET ts=? WHERE term=? AND email=?", array(time(), $term, $_SESSION['email']));
|
||||
|
||||
return $this->db->countAffected();
|
||||
}
|
||||
|
||||
|
||||
private function fixup_sphinx_operators($s = '') {
|
||||
if($s == '') { return $s; }
|
||||
|
||||
$s = preg_replace("/ OR /", "|", $s);
|
||||
$a = explode(" ", $s);
|
||||
$s = '';
|
||||
|
||||
while(list($k, $v) = each($a)) {
|
||||
|
||||
if(substr($v, 0, 4) == 'http') {
|
||||
$v = preg_replace("/http(s){0,1}\:\/\//", "__URL__", $v);
|
||||
$b = explode("/", $v);
|
||||
$s .= ' ' . $this->fix_email_address_for_sphinx($b[0]);
|
||||
}
|
||||
else {
|
||||
$s .= ' ' . $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
private function make_cache_file_name($data = array(), $sortorder = '') {
|
||||
return sha1($_SESSION['email'] . "/" . join("*", $data) . "-" . (NOW - NOW % 3600) . "-" . $sortorder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
139
webui/model/stat/chart.php
Normal file
139
webui/model/stat/chart.php
Normal file
@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
class ModelStatChart extends Model {
|
||||
|
||||
public function lineChartHamSpam($emails, $timespan, $title, $size_x, $size_y, $output){
|
||||
$ydata = array();
|
||||
$ydata2 = array();
|
||||
$dates = array();
|
||||
|
||||
$chart = new LineChart($size_x, $size_y);
|
||||
|
||||
$chart->getPlot()->getPalette()->setLineColor(array(
|
||||
//new Color(26, 192, 144),
|
||||
new Color(208, 48, 128),
|
||||
));
|
||||
|
||||
$line1 = new XYDataSet();
|
||||
|
||||
$limit = $this->getDataPoints($timespan);
|
||||
|
||||
$range = $this->getRangeInSeconds($timespan);
|
||||
|
||||
if($timespan == "daily"){ $grouping = "GROUP BY FROM_UNIXTIME(ts, '%Y.%m.%d. %H')"; }
|
||||
else { $grouping = "GROUP BY FROM_UNIXTIME(ts, '%Y.%m.%d.')"; }
|
||||
|
||||
|
||||
if($timespan == "daily"){
|
||||
$query = $this->db->query("select arrived-(arrived%3600) as ts, count(*) as num from " . TABLE_META . " where arrived > $range $emails $grouping ORDER BY ts DESC limit $limit");
|
||||
$date_format = "H:i";
|
||||
} else {
|
||||
$query = $this->db->query("select arrived-(arrived%86400) as ts, count(*) as num from " . TABLE_META . " where arrived > $range $emails $grouping ORDER BY ts DESC limit $limit");
|
||||
$date_format = "m.d.";
|
||||
}
|
||||
|
||||
foreach ($query->rows as $q) {
|
||||
array_push($ydata, $q['num']);
|
||||
array_push($dates, date($date_format, $q['ts']));
|
||||
}
|
||||
|
||||
if($query->num_rows >= 15) {
|
||||
$i = 0;
|
||||
while(list($k, $v) = each($dates)) {
|
||||
$i++;
|
||||
if($i % 3) { $dates[$k] = ""; }
|
||||
}
|
||||
reset($dates);
|
||||
}
|
||||
|
||||
|
||||
|
||||
$ydata = array_reverse($ydata);
|
||||
$dates = array_reverse($dates);
|
||||
|
||||
for($i=0; $i<count($ydata); $i++){
|
||||
$ts = $dates[$i];
|
||||
$line1->addPoint(new Point("$ts", $ydata[$i]));
|
||||
}
|
||||
|
||||
|
||||
$dataSet = new XYSeriesDataSet();
|
||||
$dataSet->addSerie("RCVD", $line1);
|
||||
|
||||
$chart->setDataSet($dataSet);
|
||||
|
||||
$chart->setTitle($title);
|
||||
$chart->getPlot()->setGraphCaptionRatio(0.80);
|
||||
|
||||
$this->sendOutput($chart, $output);
|
||||
}
|
||||
|
||||
|
||||
public function pieChartHamSpam($emails = '', $timespan, $title, $output) {
|
||||
$ham = $spam = 0;
|
||||
|
||||
$range = $this->getRangeInSeconds($timespan);
|
||||
|
||||
$chart = new PieChart(SIZE_X, SIZE_Y);
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS SPAM FROM " . TABLE_META . " WHERE $emails AND arrived > $range");
|
||||
if($query->num_rows > 0) { $spam = $query->row['SPAM']; }
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS HAM FROM " . TABLE_META . " WHERE $emails AND arrived > $range");
|
||||
if($query->num_rows > 0) { $ham = $query->row['HAM']; }
|
||||
|
||||
if($ham > $spam) {
|
||||
$chart->getPlot()->getPalette()->setPieColor(array(new Color(26, 192, 144), new Color(208, 48, 128) ));
|
||||
} else {
|
||||
$chart->getPlot()->getPalette()->setPieColor(array(new Color(208, 48, 128), new Color(26, 192, 144) ));
|
||||
}
|
||||
|
||||
|
||||
$dataSet = new XYDataSet();
|
||||
|
||||
$dataSet->addPoint(new Point("HAM ($ham)", $ham));
|
||||
$dataSet->addPoint(new Point("SPAM ($spam)", $spam));
|
||||
|
||||
$chart->setDataSet($dataSet);
|
||||
$chart->setTitle($title);
|
||||
|
||||
$this->sendOutput($chart, $output);
|
||||
}
|
||||
|
||||
|
||||
private function getRangeInSeconds($timespan) {
|
||||
$range = 0;
|
||||
|
||||
if($timespan == "daily") { return time() - 86400; }
|
||||
if($timespan == "weekly") { return time() - 604800; }
|
||||
|
||||
return time() - 2592000;
|
||||
}
|
||||
|
||||
|
||||
private function getDataPoints($timespan) {
|
||||
|
||||
if($timespan == "daily") { return 24; }
|
||||
if($timespan == "weekly") { return 7; }
|
||||
|
||||
return 30;
|
||||
}
|
||||
|
||||
|
||||
private function sendOutput($chart, $output = '') {
|
||||
if($output == "") {
|
||||
header("Content-type: image/png");
|
||||
header("Expires: now");
|
||||
}
|
||||
|
||||
if($output) {
|
||||
$chart->render($output);
|
||||
}
|
||||
else {
|
||||
$chart->render();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
43
webui/model/stat/counter.php
Normal file
43
webui/model/stat/counter.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
class ModelStatCounter extends Model {
|
||||
|
||||
public function getCounters(){
|
||||
$counter = array();
|
||||
|
||||
if(MEMCACHED_ENABLED) {
|
||||
$memcache = Registry::get('memcache');
|
||||
|
||||
$counter = $memcache->get(Registry::get('counters'));
|
||||
|
||||
if(isset($counter['_c:counters_last_update'])) { return $counter; }
|
||||
}
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_COUNTER);
|
||||
|
||||
if($query->num_rows == 1) {
|
||||
$counter = $query->row;
|
||||
}
|
||||
|
||||
return $counter;
|
||||
}
|
||||
|
||||
|
||||
public function resetCounters(){
|
||||
|
||||
if(MEMCACHED_ENABLED) {
|
||||
$memcache = Registry::get('memcache');
|
||||
|
||||
foreach (Registry::get('counters') as $counter) {
|
||||
$memcache->set($counter, 0);
|
||||
}
|
||||
}
|
||||
|
||||
$query = $this->db->query("UPDATE " . TABLE_COUNTER . " set rcvd=0, virus=0, duplicate=0, ignore=0");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
78
webui/model/user/auth.php
Normal file
78
webui/model/user/auth.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
class ModelUserAuth extends Model {
|
||||
|
||||
public function checkLogin($username = '', $password = '') {
|
||||
|
||||
$query = $this->db->query("SELECT " . TABLE_USER . ".username, " . TABLE_USER . ".uid, " . TABLE_USER . ".realname, " . TABLE_USER . ".dn, " . TABLE_USER . ".password, " . TABLE_USER . ".isadmin, " . TABLE_USER . ".domain FROM " . TABLE_USER . ", " . TABLE_EMAIL . " WHERE " . TABLE_EMAIL . ".email=? AND " . TABLE_EMAIL . ".uid=" . TABLE_USER . ".uid", array($username));
|
||||
|
||||
if(!isset($query->row['password'])) { return 0; }
|
||||
|
||||
$pass = crypt($password, $query->row['password']);
|
||||
|
||||
if($pass == $query->row['password']){
|
||||
|
||||
$_SESSION['username'] = $query->row['username'];
|
||||
$_SESSION['uid'] = $query->row['uid'];
|
||||
$_SESSION['admin_user'] = $query->row['isadmin'];
|
||||
$_SESSION['email'] = $username;
|
||||
$_SESSION['domain'] = $query->row['domain'];
|
||||
$_SESSION['realname'] = $query->row['realname'];
|
||||
|
||||
$_SESSION['emails'] = $this->model_user_user->get_users_all_email_addresses($query->row['uid']);
|
||||
|
||||
AUDIT(ACTION_LOGIN, $username, '', '', 'successful auth against user table');
|
||||
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
AUDIT(ACTION_LOGIN_FAILED, $username, '', '', 'failed auth against user table');
|
||||
}
|
||||
|
||||
if(strlen($query->row['dn']) > 3) { return $this->checkLoginAgainstLDAP($query->row, $password); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private function checkLoginAgainstLDAP($user = array(), $password = '') {
|
||||
if($password == '' || !isset($user['username']) || !isset($user['domain']) || !isset($user['dn']) || strlen($user['domain']) < 2){ return 0; }
|
||||
|
||||
$query = $this->db->query("SELECT remotehost, basedn FROM " . TABLE_REMOTE . " WHERE remotedomain=?", array($user['domain']));
|
||||
|
||||
if($query->num_rows != 1) { return 0; }
|
||||
|
||||
$ldap = new LDAP($query->row['remotehost'], $user['dn'], $password);
|
||||
|
||||
if($ldap->is_bind_ok()) {
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['admin_user'] = 0;
|
||||
$_SESSION['email'] = $user['username'];
|
||||
|
||||
$this->changePassword($user['username'], $password);
|
||||
|
||||
AUDIT(ACTION_LOGIN, $user['username'], '', '', 'changed password in local table');
|
||||
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
AUDIT(ACTION_LOGIN_FAILED, $user['username'], '', '', 'failed bind to ' . $query->row['remotehost'], $user['dn']);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function changePassword($username = '', $password = '') {
|
||||
if($username == "" || $password == ""){ return 0; }
|
||||
|
||||
$query = $this->db->query("UPDATE " . TABLE_USER . " SET password=? WHERE username=?", array(crypt($password), $username));
|
||||
|
||||
$rc = $this->db->countAffected();
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
344
webui/model/user/import.php
Normal file
344
webui/model/user/import.php
Normal file
@ -0,0 +1,344 @@
|
||||
<?php
|
||||
|
||||
|
||||
class ModelUserImport extends Model {
|
||||
|
||||
|
||||
public function getLdapParameters() {
|
||||
$my_domain = $this->model_user_user->getDomains();
|
||||
$query = $this->db->query("SELECT remotehost, basedn, binddn FROM " . TABLE_REMOTE . " WHERE remotedomain=?", array($my_domain[0]));
|
||||
|
||||
return $query->row;
|
||||
}
|
||||
|
||||
|
||||
public function queryRemoteUsers($host) {
|
||||
$data = array();
|
||||
|
||||
LOGGER("running queryRemoteUsers() ...");
|
||||
|
||||
$attrs = array("cn", "mail", "mailAlternateAddress", "memberdn", "memberaddr");
|
||||
$mailAttr = 'mail';
|
||||
$mailAttrs = array("mail", "mailalternateaddress");
|
||||
|
||||
$memberAttrs = array("memberdn");
|
||||
|
||||
$ldap = new LDAP($host['ldap_host'], $host['ldap_binddn'], $host['ldap_bindpw']);
|
||||
if($ldap->is_bind_ok() == 0) {
|
||||
LOGGER($host['ldap_binddn'] . ": failed bind to " . $host['ldap_host']);
|
||||
return array();
|
||||
}
|
||||
|
||||
LOGGER($host['ldap_binddn'] . ": successful bind to " . $host['ldap_host']);
|
||||
LOGGER("LDAP type: " . $host['type']);
|
||||
|
||||
if($host['type'] == "AD") {
|
||||
$attrs = array("cn", "proxyaddresses", "member");
|
||||
|
||||
$mailAttr = "proxyaddresses";
|
||||
$mailAttrs = array("proxyaddresses");
|
||||
|
||||
$memberAttrs = array("member");
|
||||
}
|
||||
|
||||
|
||||
$query = $ldap->query($host['ldap_basedn'], "$mailAttr=*", $attrs );
|
||||
LOGGER("LDAP query: $mailAttr=* for basedn:" . $host['ldap_basedn']);
|
||||
|
||||
foreach ($query->rows as $result) {
|
||||
$emails = "";
|
||||
|
||||
if(!isset($result['cn']) || !isset($result['dn']) ) { continue; }
|
||||
|
||||
foreach($mailAttrs as $__mail_attr) {
|
||||
|
||||
if(isset($result[$__mail_attr]) ) {
|
||||
|
||||
if(is_array($result[$__mail_attr]) ) {
|
||||
|
||||
for($i = 0; $i < $result[$__mail_attr]['count']; $i++) {
|
||||
LOGGER("found email entry: " . $result['dn'] . " => $__mail_attr:" . $result[$__mail_attr][$i]);
|
||||
if(preg_match("/^smtp\:/i", $result[$__mail_attr][$i])) {
|
||||
$emails .= strtolower(preg_replace("/^smtp\:/i", "", $result[$__mail_attr][$i])) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGGER("found email entry: " . $result['dn'] . " => $__mail_attr:" . $result[$__mail_attr]);
|
||||
$emails .= strtolower(preg_replace("/smtp\:/i", "", $result[$__mail_attr])) . "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$__emails = explode("\n", $emails);
|
||||
|
||||
|
||||
$members = "";
|
||||
|
||||
foreach($memberAttrs as $__member_attr) {
|
||||
|
||||
if(isset($result[$__member_attr]) ) {
|
||||
if(is_array($result[$__member_attr]) ) {
|
||||
for($i = 0; $i < $result[$__member_attr]['count']; $i++) {
|
||||
LOGGER("found member entry: " . $result['dn'] . " => $__member_attr:" . $result[$__member_attr][$i]);
|
||||
$members .= $result[$__member_attr][$i] . "\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGGER("found member entry: " . $result['dn'] . " => $__member_attr:" . $result[$__member_attr]);
|
||||
$members .= $result[$__member_attr] . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$data[] = array(
|
||||
'username' => preg_replace("/\n{1,}$/", "", $__emails[0]),
|
||||
'realname' => $result['cn'],
|
||||
'dn' => $result['dn'],
|
||||
'emails' => preg_replace("/\n{1,}$/", "", $emails),
|
||||
'members' => preg_replace("/\n{1,}$/", "", $members)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
LOGGER("found " . count($data) . " users");
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function fillRemoteTable($host = array(), $domain = '') {
|
||||
if($domain == '') { return 0; }
|
||||
|
||||
/*
|
||||
* if the 't_remote' table has no entry for your domain and we read some users
|
||||
* let's put the connection info to the 't_remote' table needed for proxying
|
||||
* the authentication requests
|
||||
*/
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS num FROM " . TABLE_REMOTE . " WHERE remotedomain=?", array($domain));
|
||||
|
||||
if(isset($query->row['num'])) {
|
||||
|
||||
if($query->row['num'] == 0) {
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_REMOTE . " (remotedomain, remotehost, basedn, binddn) VALUES(?,?,?,?)", array($domain, $host['ldap_host'], $host['ldap_basedn'], $host['ldap_binddn']));
|
||||
}
|
||||
else {
|
||||
$query = $this->db->query("UPDATE " . TABLE_REMOTE . " SET remotehost=?, basedn=?, binddn=? WHERE remotedomain=?", array($host['ldap_host'], $host['ldap_basedn'], $host['ldap_binddn'], $domain));
|
||||
|
||||
}
|
||||
|
||||
LOGGER("SQL exec:" . $query->query);
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function processUsers($users = array(), $globals = array()) {
|
||||
$late_add = array();
|
||||
$uids = array();
|
||||
$exclude = array();
|
||||
$newuser = 0;
|
||||
$deleteduser = 0;
|
||||
$n = 0;
|
||||
|
||||
LOGGER("running processUsers() ...");
|
||||
|
||||
/* build a list of DNs to exclude from the import */
|
||||
|
||||
while (list($k, $v) = each($globals)) {
|
||||
if(preg_match("/^reject_/", $k)) {
|
||||
$exclude[$v] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($users as $_user) {
|
||||
if(strlen($_user['dn']) > DN_MAX_LEN) { LOGGER("ERR: too long entry: " . $_user['dn']); }
|
||||
|
||||
if(in_array($_user['dn'], $exclude) ) {
|
||||
LOGGER("excluding from import:" . $_user['dn']);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Does this DN exist in the user table ? */
|
||||
|
||||
$__user = $this->model_user_user->getUserByDN($_user['dn']);
|
||||
|
||||
if(isset($__user['uid'])) {
|
||||
|
||||
array_push($uids, $__user['uid']);
|
||||
|
||||
|
||||
/* if so, then verify the email addresses */
|
||||
|
||||
$changed = 0;
|
||||
$emails = $this->model_user_user->getEmailsByUid($__user['uid']);
|
||||
|
||||
/* first let's add the new email addresses */
|
||||
|
||||
$ldap_emails = explode("\n", $_user['emails']);
|
||||
$sql_emails = explode("\n", $emails);
|
||||
|
||||
foreach ($ldap_emails as $email) {
|
||||
if(!in_array($email, $sql_emails)) {
|
||||
$rc = $this->model_user_user->addEmail($__user['uid'], $email);
|
||||
$changed++;
|
||||
|
||||
/* in case of an error add it to the $late_add array() */
|
||||
|
||||
if($rc == 0) {
|
||||
$late_add[] = array(
|
||||
'uid' => $__user['uid'],
|
||||
'email' => $email
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* delete emails not present in the user's LDAP entry */
|
||||
|
||||
foreach ($sql_emails as $email) {
|
||||
if(!in_array($email, $ldap_emails)) {
|
||||
$rc = $this->model_user_user->removeEmail($__user['uid'], $email);
|
||||
$changed++;
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER($_user['dn'] . ": exists, changed=$changed");
|
||||
|
||||
if($changed > 0) { $n++; }
|
||||
}
|
||||
else {
|
||||
|
||||
/* or add the new user */
|
||||
|
||||
$user = $this->createNewUserArray($_user['dn'], $_user['username'], $_user['realname'], $_user['emails'], $globals);
|
||||
array_push($uids, $user['uid']);
|
||||
|
||||
$rc = $this->model_user_user->addUser($user);
|
||||
if($rc == 1) { $newuser++; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* add the rest to the email table */
|
||||
|
||||
foreach ($late_add as $new) {
|
||||
$rc = $this->model_user_user->addEmail($new['uid'], $new['email']);
|
||||
if($rc == 1) { $newuser++; }
|
||||
}
|
||||
|
||||
|
||||
/* delete accounts not present in the LDAP directory */
|
||||
|
||||
if(count($uids) > 0) {
|
||||
$uidlist = implode("','", $uids);
|
||||
$query = $this->db->query("SELECT uid, username FROM " . TABLE_USER . " WHERE domain=? AND dn != '*' AND dn LIKE '%" . $globals['ldap_basedn'] . "' AND dn is NOT NULL AND uid NOT IN ('$uidlist')", array($globals['domain']) );
|
||||
|
||||
foreach ($query->rows as $deleted) {
|
||||
$deleteduser++;
|
||||
$this->model_user_user->deleteUser($deleted['uid']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* try to add new membership entries */
|
||||
|
||||
reset($users);
|
||||
|
||||
foreach ($users as $user) {
|
||||
if($user['members']) {
|
||||
|
||||
$group = $this->model_user_user->getUserByDN($user['dn']);
|
||||
|
||||
$members = explode("\n", $user['members']);
|
||||
if(count($members) > 0) {
|
||||
|
||||
if(isset($group['uid'])) {
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_EMAIL_LIST . " WHERE gid=?", array($group['uid']) );
|
||||
}
|
||||
|
||||
foreach ($members as $member) {
|
||||
if(validemail($member)) {
|
||||
$__user = $this->model_user_user->getUserByEmail($member);
|
||||
} else {
|
||||
$__user = $this->model_user_user->getUserByDN($member);
|
||||
}
|
||||
|
||||
if(isset($group['uid']) && isset($__user['uid'])) {
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_EMAIL_LIST . " (uid, gid) VALUES(?,?)", array((int)$__user['uid'], $group['uid']));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return array($newuser, $deleteduser);
|
||||
}
|
||||
|
||||
|
||||
private function createNewUserArray($dn = '', $username = '', $realname = '', $emails = '', $globals = array()) {
|
||||
$user = array();
|
||||
|
||||
$user['uid'] = $this->model_user_user->getNextUid();
|
||||
$user['gid'] = $globals['gid'];
|
||||
|
||||
$user['email'] = $emails;
|
||||
|
||||
if(USE_EMAIL_AS_USERNAME == 1) {
|
||||
$email = explode("\n", $emails);
|
||||
$user['username'] = $email[0];
|
||||
}
|
||||
else {
|
||||
$user['username'] = $username . $user['uid'];
|
||||
}
|
||||
|
||||
|
||||
$user['password'] = '*';
|
||||
|
||||
$user['realname'] = $realname;
|
||||
|
||||
if($realname == '') { $user['realname'] = $username; }
|
||||
|
||||
$user['domain'] = $globals['domain'];
|
||||
$user['dn'] = $dn;
|
||||
$user['policy_group'] = $globals['policy_group'];
|
||||
$user['isadmin'] = 0;
|
||||
$user['whitelist'] = '';
|
||||
$user['blacklist'] = '';
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
public function trashPassword($users = array()) {
|
||||
foreach ($users as $user) {
|
||||
$query = $this->db->query("UPDATE " . TABLE_USER . " SET password='*' WHERE dn=?", array($user['dn']));
|
||||
$rc = $this->db->countAffected();
|
||||
LOGGER("setting default password for " . $user['dn'] . " (rc=$rc)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function count_email_addresses() {
|
||||
$query = $this->db->query("SELECT COUNT(*) AS num FROM " . TABLE_EMAIL);
|
||||
|
||||
if(isset($query->row['num'])) { return $query->row['num']; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
45
webui/model/user/prefs.php
Normal file
45
webui/model/user/prefs.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
class ModelUserPrefs extends Model {
|
||||
|
||||
public function get_user_preferences($username = '') {
|
||||
if($username == "") { return 0; }
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_USER_SETTINGS . " WHERE username=?", array($username));
|
||||
|
||||
if(isset($query->row['pagelen'])) { $_SESSION['pagelen'] = $query->row['pagelen']; } else { $_SESSION['pagelen'] = PAGE_LEN; }
|
||||
if(isset($query->row['lang'])) { $_SESSION['lang'] = $query->row['lang']; } else { $_SESSION['lang'] = LANG; }
|
||||
if(isset($query->row['theme'])) { $_SESSION['theme'] = $query->row['theme']; } else { $_SESSION['theme'] = THEME; }
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function set_user_preferences($username = '', $prefs = array() ) {
|
||||
|
||||
if(!isset($prefs['pagelen']) || !is_numeric($prefs['pagelen']) || $prefs['pagelen'] < 10 || $prefs['pagelen'] > 100
|
||||
|| !isset($prefs['lang']) || strlen($prefs['lang']) != 2 || !file_exists(DIR_LANGUAGE . $prefs['lang'])
|
||||
|| !isset($prefs['theme']) || !preg_match("/^([a-zA-Z0-9\-\_]+)$/", $prefs['theme']) || !file_exists(DIR_THEME . $prefs['theme']) ) { return 1; }
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS num FROM " . TABLE_USER_SETTINGS . " WHERE username=?", array($username));
|
||||
|
||||
if((int)@$query->row['num'] == 1) {
|
||||
$query = $this->db->query("UPDATE " . TABLE_USER_SETTINGS . " SET lang=?, pagelen=?, theme=? WHERE username=?", array($prefs['lang'], (int)@$prefs['pagelen'], $prefs['theme'], $username));
|
||||
}
|
||||
else {
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_USER_SETTINGS . " (username, pagelen, lang, theme) VALUES(?,?,?,?)", array($username, (int)@$prefs['pagelen'], $prefs['lang'], $prefs['theme']));
|
||||
}
|
||||
|
||||
|
||||
$_SESSION['pagelen'] = $prefs['pagelen'];
|
||||
$_SESSION['lang'] = $prefs['lang'];
|
||||
$_SESSION['theme'] = $prefs['theme'];
|
||||
|
||||
LOGGER("set user preference", $username);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
421
webui/model/user/user.php
Normal file
421
webui/model/user/user.php
Normal file
@ -0,0 +1,421 @@
|
||||
<?php
|
||||
|
||||
class ModelUserUser extends Model {
|
||||
|
||||
|
||||
public function checkUID($uid) {
|
||||
if($uid == "") { return 0; }
|
||||
|
||||
if(!is_numeric($uid)) { return 0; }
|
||||
|
||||
if($uid < 1) { return 0; }
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function getUidByName($username = '') {
|
||||
if($username == ""){ return -1; }
|
||||
|
||||
$query = $this->db->query("SELECT uid FROM " . TABLE_USER . " WHERE username=?", array($username));
|
||||
|
||||
if(isset($query->row['uid'])){
|
||||
return $query->row['uid'];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public function getUsernameByUid($uid = 0) {
|
||||
|
||||
$query = $this->db->query("SELECT username FROM " . TABLE_USER . " WHERE uid=?", array((int)$uid));
|
||||
|
||||
if(isset($query->row['username'])){
|
||||
return $query->row['username'];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public function get_uid_by_email($email = '') {
|
||||
$query = $this->db->query("SELECT uid FROM " . TABLE_EMAIL . " WHERE email=?", array($email));
|
||||
|
||||
if(isset($query->row['uid'])){ return $query->row['uid']; }
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public function get_username_by_email($email = '') {
|
||||
$query = $this->db->query("SELECT username FROM " . TABLE_USER . ", " . TABLE_EMAIL . " WHERE " . TABLE_USER . ".uid=" . TABLE_EMAIL . ".uid AND email=?", array($email));
|
||||
|
||||
if(isset($query->row['username'])){ return $query->row['username']; }
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public function get_users_all_email_addresses($uid = 0) {
|
||||
$data = array();
|
||||
$uids = $uid;
|
||||
|
||||
if($uid > 0) {
|
||||
$query = $this->db->query("SELECT gid FROM " . TABLE_EMAIL_LIST . " WHERE uid=?", array((int)$uid));
|
||||
|
||||
if(isset($query->rows)) {
|
||||
foreach ($query->rows as $q) {
|
||||
if(is_numeric($q['gid']) && $q['gid'] > 0) {
|
||||
$uids .= "," . $q['gid'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$query = $this->db->query("SELECT email FROM " . TABLE_EMAIL . " WHERE uid IN ($uids)");
|
||||
foreach ($query->rows as $q) {
|
||||
array_push($data, $q['email']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function get_additional_uids($uid = 0) {
|
||||
$data = array();
|
||||
|
||||
if($uid > 0) {
|
||||
$query = $this->db->query("SELECT gid FROM " . TABLE_EMAIL_LIST . " WHERE uid=?", array((int)$uid));
|
||||
|
||||
if(isset($query->rows)) {
|
||||
foreach ($query->rows as $q) {
|
||||
array_push($data, $q['gid']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function getEmailAddress($username = '') {
|
||||
|
||||
$query = $this->db->query("SELECT " . TABLE_EMAIL . ".email AS email FROM " . TABLE_EMAIL . "," . TABLE_USER . " WHERE " . TABLE_EMAIL . ".uid=" . TABLE_USER . ".uid AND " . TABLE_USER . ".username=? LIMIT 1", array($username));
|
||||
|
||||
if(isset($query->row['email'])){
|
||||
return $query->row['email'];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
public function getEmails($username = '') {
|
||||
$emails = "";
|
||||
|
||||
$query = $this->db->query("SELECT " . TABLE_EMAIL . ".email AS email FROM " . TABLE_EMAIL . "," . TABLE_USER . " WHERE " . TABLE_EMAIL . ".uid=" . TABLE_USER . ".uid AND " . TABLE_USER . ".username=?", array($username));
|
||||
|
||||
foreach ($query->rows as $q) {
|
||||
$emails .= $q['email'] . "\n";
|
||||
}
|
||||
|
||||
return preg_replace("/\n$/", "", $emails);
|
||||
}
|
||||
|
||||
|
||||
public function getEmailsByUid($uid = 0) {
|
||||
$emails = "";
|
||||
|
||||
$query = $this->db->query("SELECT email FROM " . TABLE_EMAIL . " WHERE uid=?", array((int)$uid));
|
||||
foreach ($query->rows as $q) {
|
||||
$emails .= $q['email'] . "\n";
|
||||
}
|
||||
|
||||
return preg_replace("/\n$/", "", $emails);
|
||||
}
|
||||
|
||||
|
||||
public function getUserByDN($dn = '') {
|
||||
if($dn == '') { return array(); }
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_USER . " WHERE dn=?", array($dn));
|
||||
|
||||
if($query->num_rows == 1) {
|
||||
return $query->row;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
public function getUserByUid($uid = 0) {
|
||||
if(!is_numeric($uid) || (int)$uid < 0){
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_USER . " WHERE uid=?", array((int)$uid));
|
||||
|
||||
return $query->row;
|
||||
}
|
||||
|
||||
|
||||
public function getUserByEmail($email = '') {
|
||||
if($email == '') {
|
||||
return array();
|
||||
}
|
||||
|
||||
$query = $this->db->query("SELECT * FROM " . TABLE_USER . "," . TABLE_EMAIL . " WHERE " . TABLE_USER . ".uid=" . TABLE_EMAIL . ".uid AND email=?", array($email));
|
||||
|
||||
return $query->row;
|
||||
}
|
||||
|
||||
|
||||
public function getUsernameByEmail($email = '') {
|
||||
$username = "";
|
||||
|
||||
if($email == '') { return $username; }
|
||||
|
||||
$query = $this->db->query("SELECT username FROM " . TABLE_USER . " WHERE uid IN (SELECT uid FROM " . TABLE_EMAIL . " WHERE email=?)", array($email));
|
||||
|
||||
if(isset($query->row['username'])) { $username = $query->row['username']; }
|
||||
|
||||
return $username;
|
||||
}
|
||||
|
||||
|
||||
public function getUsers($search = '', $page = 0, $page_len = 0, $sort = 'username', $order = 0) {
|
||||
$where_cond = " WHERE " . TABLE_USER . ".uid=" . TABLE_EMAIL . ".uid ";
|
||||
$_order = "";
|
||||
$users = array();
|
||||
$my_domain = array();
|
||||
$limit = "";
|
||||
|
||||
$from = (int)$page * (int)$page_len;
|
||||
|
||||
$search = preg_replace("/\s{1,}/", "", $search);
|
||||
|
||||
if($search){
|
||||
$where_cond .= " AND email like '%" . $this->db->escape($search) . "%' ";
|
||||
}
|
||||
|
||||
/* sort order */
|
||||
|
||||
if($order == 0) { $order = "ASC"; }
|
||||
else { $order = "DESC"; }
|
||||
|
||||
$_order = "ORDER BY $sort $order";
|
||||
|
||||
if($page_len > 0) { $limit = " LIMIT " . (int)$from . ", " . (int)$page_len; }
|
||||
|
||||
$query = $this->db->query("SELECT " . TABLE_USER . ".uid, isadmin, username, realname, domain, email FROM " . TABLE_USER . "," . TABLE_EMAIL . " $where_cond group by " . TABLE_USER . ".uid $_order $limit");
|
||||
|
||||
foreach ($query->rows as $q) {
|
||||
|
||||
if(Registry::get('admin_user') == 1 || (isset($q['domain']) && $q['domain'] == $my_domain[0]) ) {
|
||||
$users[] = array(
|
||||
'uid' => $q['uid'],
|
||||
'username' => $q['username'],
|
||||
'realname' => $q['realname'],
|
||||
'domain' => isset($q['domain']) ? $q['domain'] : "",
|
||||
'email' => $q['email'],
|
||||
'isadmin' => $q['isadmin']
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
|
||||
|
||||
public function howManyUsers($search = '') {
|
||||
$where_cond = "";
|
||||
|
||||
if($search){
|
||||
$where_cond .= " WHERE email like '%" . $this->db->escape($search) . "%' ";
|
||||
}
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS num, uid FROM " . TABLE_EMAIL . " $where_cond group by uid");
|
||||
|
||||
return $query->num_rows;
|
||||
}
|
||||
|
||||
|
||||
public function get_domains() {
|
||||
$data = array();
|
||||
|
||||
$query = $this->db->query("SELECT DISTINCT mapped AS domain FROM " . TABLE_DOMAIN);
|
||||
|
||||
foreach ($query->rows as $q) {
|
||||
array_push($data, $q['domain']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function get_email_domains() {
|
||||
$data = array();
|
||||
|
||||
$query = $this->db->query("SELECT domain FROM " . TABLE_DOMAIN);
|
||||
|
||||
foreach ($query->rows as $q) {
|
||||
array_push($data, $q['domain']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
public function getNextUid() {
|
||||
|
||||
$query = $this->db->query("SELECT MAX(uid) AS last_id FROM " . TABLE_USER);
|
||||
|
||||
if(isset($query->row['last_id']) && $query->row['last_id'] > 0) {
|
||||
return (int)$query->row['last_id'] + 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function addUser($user) {
|
||||
LOGGER("add user: " . $user['username'] . ", uid=" . (int)$user['uid']);
|
||||
|
||||
if(!isset($user['domain']) || $user['domain'] == "") { return -1; }
|
||||
if(!isset($user['username']) || $user['username'] == "" || $this->getUidByName($user['username']) > 0) { return -1; }
|
||||
|
||||
$emails = explode("\n", $user['email']);
|
||||
foreach ($emails as $email) {
|
||||
$email = rtrim($email);
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS count FROM " . TABLE_EMAIL . " WHERE email=?", array($email));
|
||||
|
||||
/* remove from memcached */
|
||||
|
||||
if(MEMCACHED_ENABLED) {
|
||||
$memcache = Registry::get('memcache');
|
||||
$memcache->delete("_c:" . $email);
|
||||
}
|
||||
|
||||
if($query->row['count'] > 0) {
|
||||
return $email;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS count FROM " . TABLE_USER . " WHERE username=?", array($user['username']));
|
||||
if($query->row['count'] > 0) {
|
||||
return $user['username'];
|
||||
}
|
||||
|
||||
$encrypted_password = crypt($user['password']);
|
||||
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_USER . " (uid, username, realname, password, domain, dn, isadmin) VALUES(?,?,?,?,?,?,?)", array((int)$user['uid'], $user['username'], $user['realname'], $encrypted_password, $user['domain'], @$user['dn'], (int)$user['isadmin']));
|
||||
|
||||
if($query->error == 1 || $this->db->countAffected() == 0){ return $user['username']; }
|
||||
|
||||
foreach ($emails as $email) {
|
||||
$email = rtrim($email);
|
||||
|
||||
$ret = $this->addEmail((int)$user['uid'], $email);
|
||||
if($ret == 0) { return -2; }
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function addEmail($uid = 0, $email = '') {
|
||||
if($uid < 1 || $email == ""){ return 0; }
|
||||
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_EMAIL . " (uid, email) VALUES(?,?)", array((int)$uid, $email));
|
||||
|
||||
$rc = $this->db->countAffected();
|
||||
|
||||
LOGGER("add email: $email, uid=$uid (rc=$rc)");
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
public function removeEmail($uid = 0, $email = '') {
|
||||
if((int)$uid < 1 || $email == ""){ return 0; }
|
||||
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_EMAIL . " WHERE uid=? AND email=?", array((int)$uid, $email));
|
||||
|
||||
$rc = $this->db->countAffected();
|
||||
|
||||
LOGGER("remove email: $email, uid=$uid (rc=$rc)");
|
||||
|
||||
return $rc;
|
||||
}
|
||||
|
||||
|
||||
public function updateUser($user) {
|
||||
LOGGER("update user: " . $user['username'] . ", uid=" . (int)$user['uid']);
|
||||
|
||||
$emails = explode("\n", $user['email']);
|
||||
foreach ($emails as $email) {
|
||||
$email = rtrim($email);
|
||||
|
||||
$query = $this->db->query("SELECT COUNT(*) AS count FROM " . TABLE_EMAIL . " WHERE uid!=? AND email=?", array((int)$user['uid'], $email));
|
||||
|
||||
if($query->row['count'] > 0) {
|
||||
return $email;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* update password field if we have to */
|
||||
|
||||
if(strlen($user['password']) >= MIN_PASSWORD_LENGTH) {
|
||||
$query = $this->db->query("UPDATE " . TABLE_USER . " SET password=? WHERE uid=?", array(crypt($user['password']), (int)$user['uid']));
|
||||
if($this->db->countAffected() != 1) { return 0; }
|
||||
}
|
||||
|
||||
$query = $this->db->query("UPDATE " . TABLE_USER . " SET username=?, realname=?, domain=?, dn=?, isadmin=? WHERE uid=?", array($user['username'], $user['realname'], $user['domain'], @$user['dn'], $user['isadmin'], (int)$user['uid']));
|
||||
|
||||
|
||||
/* first, remove all his email addresses */
|
||||
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_EMAIL . " WHERE uid=?", array((int)$user['uid']));
|
||||
|
||||
/* then add all the emails we have from the CGI post input */
|
||||
|
||||
foreach ($emails as $email) {
|
||||
$email = rtrim($email);
|
||||
$query = $this->db->query("INSERT INTO " . TABLE_EMAIL . " (uid, email) VALUES(?,?)", array((int)$user['uid'], $email));
|
||||
|
||||
/* remove from memcached */
|
||||
|
||||
if(MEMCACHED_ENABLED) {
|
||||
$memcache = Registry::get('memcache');
|
||||
$memcache->delete("_c:" . $email);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public function deleteUser($uid) {
|
||||
if(!$this->checkUID($uid)){ return 0; }
|
||||
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_EMAIL . " WHERE uid=?", array((int)$uid));
|
||||
$query = $this->db->query("DELETE FROM " . TABLE_USER . " WHERE uid=?", array((int)$uid));
|
||||
|
||||
LOGGER("remove user: uid=$uid");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
?>
|
Reference in New Issue
Block a user