From: liedekef Date: Fri, 17 Feb 2023 15:55:54 +0000 (+0100) Subject: update the php code to work with php 8, add the possibility to edit texts, see the... X-Git-Tag: RELEASE_1_4_0b1~104 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41a83d7501d41a2aa9c780b9070be4c7bf474cf6;p=thirdparty%2Fmlmmj.git update the php code to work with php 8, add the possibility to edit texts, see the log and limit who can manage per list the settings or subscribers --- diff --git a/contrib/web/php-admin/README b/contrib/web/php-admin/README index 36f57b73..e087487d 100644 --- a/contrib/web/php-admin/README +++ b/contrib/web/php-admin/README @@ -46,4 +46,11 @@ To use this web-interface you have to: It will then ask you for a password for the given username. -6) That is it, you are ready to use the interface. +6) Use 2 extra configs to limit per list the people who can access the php admin itf and/or who can manage the subscribers + To limit who can access the php admin interface per list, create for the list in question the control file admin_users + and put in it the userids of the people allowed to manage just that list (one per line) + To limit who can manage subscribers per list, create for the list in question the control file subsadmin_users + and put in it the userids of the people allowed to manage subscribers just that list (one per line) + If subsadmin_users does not exist and admin_users exists, the content of that file will be used. + +7) That is it, you are ready to use the interface. diff --git a/contrib/web/php-admin/htdocs/class.rFastTemplate.php b/contrib/web/php-admin/htdocs/class.rFastTemplate.php index f5979562..c4a29efe 100644 --- a/contrib/web/php-admin/htdocs/class.rFastTemplate.php +++ b/contrib/web/php-admin/htdocs/class.rFastTemplate.php @@ -192,7 +192,8 @@ class rFastTemplate { // Description // Constructor. // - function rFastTemplate ($pathToTemplates = '') { + //function rFastTemplate ($pathToTemplates = '') { + public function __construct ($pathToTemplates = '') { // $pathToTemplates can also be an array of template roots, handled in set_root global $php_errormsg; @@ -317,7 +318,7 @@ class rFastTemplate { $this->ROOT[] = $root; } else { reset($root); - while(list($k, $v) = each($root)) { + foreach ($root as $k=>$v) { if (is_dir($v)) { $trailer = substr ($v,-1); if ($trailer != ($this->WIN32 ? '\\' : '/')) @@ -341,7 +342,7 @@ class rFastTemplate { // function define ($fileList, $dynamic = 0) { reset ($fileList); - while (list ($tpl, $file) = each ($fileList)) { + foreach ($fileList as $tpl=>$file) { $this->TEMPLATE[$tpl] = array ('file' => $file, 'dynamic' => $dynamic); } return true; @@ -350,7 +351,7 @@ class rFastTemplate { function define_dynamic ($tplList, $parent='') { if (is_array($tplList)) { reset ($tplList); - while (list ($tpl, $parent) = each ($tplList)) { + foreach ($tplList as $tpl=>$parent) { $this->TEMPLATE[$tpl]['parent'] = $parent; $this->TEMPLATE[$tpl]['dynamic'] = true; } @@ -371,7 +372,7 @@ class rFastTemplate { // function define_raw ($stringList, $dynamic = 0) { reset ($stringList); - while (list ($tpl, $string) = each ($stringList)) { + foreach ($stringList as $tpl=>$string) { $this->TEMPLATE[$tpl] = array ('string' => $string, 'dynamic' => $dynamic, 'loaded' => 1); } return true; @@ -393,7 +394,7 @@ class rFastTemplate { // search path for a matching file reset($this->ROOT); - while(list($k, $v) = each($this->ROOT)) { + foreach ($this->ROOT as $k=>$v) { $f = $v . $file; if (file_exists($f)) { return $f; @@ -474,7 +475,7 @@ class rFastTemplate { // whitespace. If so, we delete the entire line. $okay = false; for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) { - $c = $rest{$offbeg}; + $c = $rest[$offbeg]; if ($c == "\n") { $okay = true; $offbeg++; @@ -490,7 +491,7 @@ class rFastTemplate { } else { $l = strlen ($rest); for ($offend = $pos + strlen($dynbeg[1]); $offend < $l; $offend++) { - $c = $rest{$offend}; + $c = $rest[$offend]; if ($c == "\n") { $offend++; break; @@ -534,7 +535,7 @@ class rFastTemplate { // only whitespace. If so, we delete the entire line. $okay = false; for ($offbeg = $pos - 1; $offbeg >= 0; $offbeg--) { - $c = $rest{$offbeg}; + $c = $rest[$offbeg]; if ($c == "\n") { $offbeg++; $okay = true; @@ -550,7 +551,7 @@ class rFastTemplate { } else { $l = strlen ($rest); for ($offend = $pos + strlen($dynend[1]); $offend < $l; $offend++) { - $c = $rest{$offend}; + $c = $rest[$offend]; if ($c == "\n") { $offend++; break; @@ -804,14 +805,14 @@ class rFastTemplate { // Because we treat VAR and HANDLE separately (unlike // class.FastTemplate.php3), we have to iterate over both or we // miss some substitutions and are not 100% compatible. - while (list($key,$val) = each ($this->VAR)) { + foreach ($this->VAR as $key=>$val) { if ($debug) $this->logwrite ("subst: substituting VAR $key = $val in $tag"); $key = '{'.$key.'}'; $tmp = str_replace ($key, $val, $tmp); } reset ($this->HANDLE); - while (list($key,$val) = each ($this->HANDLE)) { + foreach ($this->HANDLE as $key=>$val) { if ($debug) $this->logwrite ("subst: substituting HANDLE $key = $val in $tag"); $key = '{'.$key.'}'; @@ -983,7 +984,7 @@ class rFastTemplate { function setkey ($tplkey, $rest = '') { if (gettype ($tplkey) == 'array') { reset ($tplkey); - while (list($key,$val) = each ($tplkey)) { + foreach ($tplkey as $key=>$val) { if (!empty($key)) { $this->VAR[$key] = $val; } @@ -998,7 +999,7 @@ class rFastTemplate { function append ($tplkey, $rest = '') { if (gettype ($tplkey) == 'array') { reset ($tplkey); - while (list($key,$val) = each ($tplkey)) { + foreach ($tplkey as $key=>$val) { if (!empty($key)) { $this->VAR[$key] .= $val; } diff --git a/contrib/web/php-admin/htdocs/edit.php b/contrib/web/php-admin/htdocs/edit.php index 21791828..83c1d28e 100644 --- a/contrib/web/php-admin/htdocs/edit.php +++ b/contrib/web/php-admin/htdocs/edit.php @@ -1,6 +1,7 @@ * Copyright (C) 2004 Christoph Thiel * * mlmmj/php-perl: @@ -40,7 +41,7 @@ function mlmmj_boolean($name, $nicename, $text) $tpl->assign(array("NAME" => htmlentities($name), "NICENAME" => htmlentities($nicename), - "TEXT" => htmlentities($text))); + "TEXT" => nl2br(htmlentities($text)))); $tpl->assign(array("CHECKED" => $checked ? " checked" : "")); $tpl->parse("ROWS",".boolean"); @@ -63,7 +64,7 @@ function mlmmj_string($name, $nicename, $text) $tpl->assign(array("NAME" => htmlentities($name), "NICENAME" => htmlentities($nicename), - "TEXT" => htmlentities($text), + "TEXT" => nl2br(htmlentities($text)), "VALUE" => htmlentities($value))); $tpl->parse("ROWS",".string"); @@ -85,7 +86,7 @@ function mlmmj_list($name, $nicename, $text) $tpl->assign(array("NAME" => htmlentities($name), "NICENAME" => htmlentities($nicename), - "TEXT" => htmlentities($text), + "TEXT" => nl2br(htmlentities($text)), "VALUE" => htmlentities($value))); $tpl->parse("ROWS",".list"); @@ -97,10 +98,9 @@ function encode_entities($str) { return htmlentities($str); } $tpl = new rFastTemplate($templatedir); -$list = $_GET["list"]; - -if(!isset($list)) -die("no list specified"); +if(empty($_GET['list'])) + die("no list specified"); +$list = $_GET['list']; if (dirname(realpath($topdir."/".$list)) != realpath($topdir)) die("list outside topdir"); @@ -108,6 +108,24 @@ die("list outside topdir"); if(!is_dir($topdir."/".$list)) die("non-existent list"); +$userfile = "$topdir/$list/control/admin_users"; +if (is_file($userfile)) { + // read users into array + $admin_users = array_map('trim',file($userfile)); + // remove empty values from array + $admin_users = array_filter($admin_users); + if (!isset($_SERVER['PHP_AUTH_USER']) || !in_array($_SERVER['PHP_AUTH_USER'],$admin_users)) { + header("WWW-Authenticate: " . + "Basic realm=\"Mlmmj Protected Area\""); + header("HTTP/1.0 401 Unauthorized"); + //Show failure text, which browsers usually + //show only after several failed attempts + print("This page is protected by HTTP " . + "Authentication.
\n"); + exit; + } +} + $tpl->define(array("main" => "edit.html", "boolean" => "edit_boolean.html", "string" => "edit_string.html", diff --git a/contrib/web/php-admin/htdocs/index.php b/contrib/web/php-admin/htdocs/index.php index 2aa91fff..36396e44 100644 --- a/contrib/web/php-admin/htdocs/index.php +++ b/contrib/web/php-admin/htdocs/index.php @@ -1,6 +1,7 @@ * Copyright (C) 2004 Christoph Thiel * * mlmmj/php-perl: @@ -36,12 +37,58 @@ $tpl->define(array("main" => "index.html")); $lists = ""; # use scandir to have alphabetical order -foreach (scandir($topdir) as $file) { - if (!ereg("^\.",$file)) - { - $lists .= "

".htmlentities($file)."
\n"; - $lists .= "Config - Subscribers\n"; - $lists .= "

\n"; +foreach (scandir($topdir) as $mlmmj_list) { + if (substr($mlmmj_list,0,1) != '.' && file_exists("$topdir/$mlmmj_list/control")) { + $admin_userfile = "$topdir/$mlmmj_list/control/admin_users"; + $subs_userfile = "$topdir/$mlmmj_list/control/subsadmin_users"; + if (!is_file($subs_userfile)) { + $subs_userfile = "$topdir/$mlmmj_list/control/admin_users"; + } + + if (isset($_SERVER['PHP_AUTH_USER']) && is_file($admin_userfile)) { + // read users into array + $admin_users = array_map('trim',file($admin_userfile)); + // remove empty values from array + $admin_users = array_filter($admin_users); + if (in_array($_SERVER['PHP_AUTH_USER'],$admin_users)) { + $print_config=1; + } else { + $print_config=0; + } + } else { + $print_config=1; + } + if (isset($_SERVER['PHP_AUTH_USER']) && is_file($subs_userfile)) { + // read users into array + $subs_users = array_map('trim',file($subs_userfile)); + // remove empty values from array + $subs_users = array_filter($subs_users); + if (in_array($_SERVER['PHP_AUTH_USER'],$subs_users)) { + $print_sub=1; + } else { + $print_sub=0; + } + } else { + $print_sub=1; + } + + if ($print_config || $print_sub) { + $lists .= "

".htmlentities($mlmmj_list)."
\n"; + + if ($print_config) { + $lists .= "Config - "; + $lists .= "Text files"; + } + if ($print_config && $print_sub) + $lists .= " - "; + if ($print_sub) + $lists .= "Subscribers\n"; + + if ($print_config) + $lists .= " - Log"; + + $lists .= "

\n"; + } } } diff --git a/contrib/web/php-admin/htdocs/save.php b/contrib/web/php-admin/htdocs/save.php index 73f249f6..5d44310b 100644 --- a/contrib/web/php-admin/htdocs/save.php +++ b/contrib/web/php-admin/htdocs/save.php @@ -1,6 +1,7 @@ * Copyright (C) 2004 Christoph Thiel * * mlmmj/php-perl: @@ -39,8 +40,10 @@ function mlmmj_boolean($name, $nicename, $text) { if(!touch($file)) die("Couldn't open ".$file." for writing"); - if (!chmod($file, 0644)) - die("Couldn't chmod ".$file); + //if (!chmod($file, 0644)) + // die("Couldn't chmod ".$file); + // don't error on chmod, if the owner of the file is different it won't work + @chmod($file, 0664); } else { if (file_exists($file)) { @@ -80,8 +83,10 @@ function mlmmj_list($name, $nicename, $text) fwrite($fp, $_POST[$name]); fclose($fp); - if (!chmod($file, 0644)) - die("Couldn't chmod ".$file); + //if (!chmod($file, 0644)) + // die("Couldn't chmod ".$file); + // don't error on chmod, if the owner of the file is different it won't work + @chmod($file, 0664); } else { if (file_exists($file)) { @@ -97,10 +102,9 @@ function encode_entities($str) { return htmlentities($str); } $tpl = new rFastTemplate($templatedir); -$list = $_POST["list"]; - -if(!isset($list)) -die("no list specified"); +if(empty($_POST['list'])) + die("no list specified"); +$list = $_POST['list']; if (dirname(realpath($topdir."/".$list)) != realpath($topdir)) die("list outside topdir"); @@ -108,6 +112,25 @@ die("list outside topdir"); if(!is_dir($topdir."/".$list)) die("non-existent list"); +$userfile = "$topdir/$list/control/admin_users"; +$admin_user = ""; +if(is_file($userfile)) { + // read users into array + $admin_users = array_map('trim',file($userfile)); + // remove empty values from array + $admin_users = array_filter($admin_users); + if (!isset($_SERVER['PHP_AUTH_USER']) || !in_array($_SERVER['PHP_AUTH_USER'],$admin_users)) { + header("WWW-Authenticate: " . + "Basic realm=\"Mlmmj Protected Area\""); + header("HTTP/1.0 401 Unauthorized"); + //Show failure text, which browsers usually + //show only after several failed attempts + print("This page is protected by HTTP " . + "Authentication.
\n"); + exit; + } +} + $tpl->define(array("main" => "save.html")); $tpl->assign(array("LIST" => htmlentities($list))); diff --git a/contrib/web/php-admin/htdocs/subscribers.php b/contrib/web/php-admin/htdocs/subscribers.php index 4c5444ac..2f11897d 100644 --- a/contrib/web/php-admin/htdocs/subscribers.php +++ b/contrib/web/php-admin/htdocs/subscribers.php @@ -1,6 +1,12 @@ +/* mlmmj/php-admin: + * Copyright (C) 2023 Franky Van Liedekerke + * Copyright (C) 2004 Christoph Thiel + * + * mlmmj/php-perl: + * Copyright (C) 2004 Morten K. Poulsen + * Copyright (C) 2004 Christian Laursen * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -27,10 +33,9 @@ require(dirname(__FILE__)."/class.rFastTemplate.php"); $tpl = new rFastTemplate($templatedir); # get the list parameter and check that list exists -$list = $_GET["list"]; - -if(!isset($list)) -die("no list specified"); +if(empty($_GET['list'])) + die("no list specified"); +$list = $_GET['list']; if (dirname(realpath($topdir."/".$list)) != realpath($topdir)) die("list outside topdir"); @@ -38,7 +43,28 @@ die("list outside topdir"); if(!is_dir($topdir."/".$list)) die("non-existent list"); -# this will be displayed on the top of the page +$userfile = "$topdir/$list/control/subsadmin_users"; +if (!is_file($userfile)) { + $userfile = "$topdir/$list/control/admin_users"; +} +$admin_user = ""; +if (is_file($userfile)) { + // read users into array + $admin_users = array_map('trim',file($userfile)); + // remove empty values from array + $admin_users = array_filter($admin_users); + if (!isset($_SERVER['PHP_AUTH_USER']) || !in_array($_SERVER['PHP_AUTH_USER'],$admin_users)) { + header("WWW-Authenticate: " . + "Basic realm=\"Mlmmj Protected Area\""); + header("HTTP/1.0 401 Unauthorized"); + //Show failure text, which browsers usually + //show only after several failed attempts + print("This page is protected by HTTP " . + "Authentication.
\n"); + exit; + } +} + $message = ""; # subscribe some people if tosubscribe is set @@ -48,7 +74,7 @@ if (isset($_POST["tosubscribe"])) { $email = trim($line); if ($email != "") { if (filter_var($email, FILTER_VALIDATE_EMAIL)) { - $cmd = "/usr/bin/mlmmj-sub -L ".escapeshellarg("$topdir/$list")." -a ".escapeshellarg($email)." 2>&1"; + $cmd = "/usr/bin/mlmmj-sub -f -q -s -L ".escapeshellarg("$topdir/$list")." -a ".escapeshellarg($email)." 2>&1"; unset($out); exec($cmd, $out, $ret); if ($ret !== 0) { @@ -67,7 +93,7 @@ if (isset($_POST["tosubscribe"])) { $email = $_POST["email"]; if (! filter_var($email, FILTER_VALIDATE_EMAIL)) die("Email address not valid"); - $cmd = "/usr/bin/mlmmj-unsub -L ".escapeshellarg("$topdir/$list")." -a ".escapeshellarg($email)." 2>&1"; + $cmd = "/usr/bin/mlmmj-unsub -q -s -L ".escapeshellarg("$topdir/$list")." -a ".escapeshellarg($email)." 2>&1"; unset($out); exec($cmd, $out, $ret); if ($ret !== 0) { @@ -78,7 +104,7 @@ if (isset($_POST["tosubscribe"])) { $subscribers=""; # get subscribers from mlmmj -$cmd = "/usr/bin/mlmmj-list -L ".escapeshellarg("$topdir/$list")." 2>&1"; +$cmd = "/usr/bin/mlmmj-list -L ".escapeshellarg("$topdir/$list")." |sort"; unset($out); exec($cmd, $out, $ret); if ($ret !== 0) { @@ -96,8 +122,8 @@ if ($ret !== 0) { $subscribers.= "".htmlspecialchars($email)."$form\n"; } - if ($subscribers === "") { - $subscribers = "This list is empty.\n"; + if (empty($subscribers)) { + $subscribers = "This list is empty or the permissions are not set correctly to get the subscribers.\n"; } }