Compare commits

...

55 Commits

Author SHA1 Message Date
0f2e2b82aa * Tue Jun 24 2025 Brian Read <brianr@koozali.org> 11.0.0-95.sme
- Add clock ticker to datetime panel [SME: 13054]
- Add Test Server button for ntp server [SME: 13048]
- Add checking that date is fully valid [SME: 13055]
2025-06-25 10:35:16 +01:00
0341d02608 * Thu Jun 19 2025 Brian Read <brianr@koozali.org> 11.0.0-94.sme
- re-instate datetime routes in SrvMngr.pm - removed by mistake [SME: 13053]
2025-06-19 10:36:50 +01:00
c208419704 * Thu Jun 19 2025 Brian Read <brianr@koozali.org> 11.0.0-93.sme
- Sort out case of first letter of ctlact in routes added in from header on controller file [SME: 13053]
2025-06-19 06:26:38 +01:00
d1f2013375 * Sun Jun 15 2025 Brian Read <brianr@koozali.org> 11.0.0-92.sme
- rework datetime panel [SME: 13020]
- Fix errors in error messages for local networks panel [SME: 13044]
- Add in Config Db open in Proxy.pm needed after  UTF8 change [SME: 13046]
2025-06-18 11:17:51 +01:00
0733537064 * Fri Jun 13 2025 Brian Read <brianr@koozali.org> 11.0.0-91.sme
- Port Forwarding  - Same error as in local networking [SME: 13043]
2025-06-13 17:04:22 +01:00
dcc098b206 * Thu Jun 12 2025 Brian Read <brianr@koozali.org> 11.0.0-90.sme
- Error on empty extra chars for success message [SME: 13041]
- Needed extra open for network-db after add
2025-06-12 19:15:22 +01:00
1a8f935431 * Thu Jun 12 2025 Brian Read <brianr@koozali.org> 11.0.0-89.sme
- rework navigation weights to avoid duplicates [SME: 12996]
2025-06-12 18:15:41 +01:00
e8d6d39583 * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-88.sme
- add datetime getYear_list [SME: 13031]
- use esmith::*DB::UTF8 to access db flat files [SME: 13027]
- fix typo [SME: 13038]
2025-06-10 07:17:32 -04:00
91201b7b02 * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-87.sme
- add datetime getYear_list [SME: 13031]
- use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-10 00:09:39 -04:00
c85022c49e * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-87.sme
- add datetime getYear_list [SME: 13031]
- use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-09 23:49:25 -04:00
fd076895ba * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-87.sme
- add datetime getYear_list [SME: 13031]
- WIP use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-09 12:49:29 -04:00
John Crisp
d993bd9d19 Fix DateTime gen_locale_date_string 2025-06-09 14:08:56 +02:00
John Crisp
a31806f205 Add UTF8 support to local network panel 2025-06-09 13:39:32 +02:00
b44f1c5000 * Mon Jun 09 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-84.sme
- fix Directory caching issue [SME: 13026]
- WIP use esmith::*DB::UTF8 to access db flat files [SME: 13027]
2025-06-09 00:46:19 -04:00
2538ac9ea0 * Mon May 05 2025 Brian Read <brianr@koozali.org> 11.0.0-83.sme
- Mod to SrvMngr-Auth to account for partials matching AdminPanels options
2025-05-05 07:01:25 +01:00
dbfeaa18a3 * Thu May 01 2025 Brian Read <brianr@koozali.org> 11.0.0-82.sme
- Correct Weights for menus [SME: 12996]
2025-05-01 18:16:25 +01:00
ced08b28d4 Update version in spec 2025-05-01 13:29:52 +01:00
c74a71dee1 * Thu May 01 2025 Brian Read <brianr@koozali.org> 11.0.0-81.sme
- Correct Weights for menus [SME: 12996]
2025-05-01 12:07:55 +01:00
96b002e7a9 * Wed Apr 30 2025 Brian Read <brianr@koozali.org> 11.0.0-80.sme
- Remove expansion of css files from createlinks [SME: 12989]
2025-05-01 06:33:46 +01:00
f30b4ab2b5 * Wed Apr 30 2025 Brian Read <brianr@koozali.org> 11.0.0-79.sme
- Add code in SrvMngr to take note of user panel setting
2025-04-30 09:09:16 +01:00
fa286e966d * Thu Apr 17 2025 Brian Read <brianr@koozali.org> 11.0.0-78.sme
- typo in remoteaccess panel
- Fix crash in veiwlogfiles if viewlogfiles key not in DB
2025-04-17 12:16:38 +01:00
9bb2128891 Typo in name for remoteaccess panel 2025-04-16 17:48:37 +01:00
accf96df0d * Sat Apr 12 2025 Brian Read <brianr@koozali.org> 11.0.0-77.sme
- Sort out local and pulic access setting in remote panel  [SME: 12988]
- caching problem, plus confusion between normal and public setting in sshd / access in DB
2025-04-12 09:08:12 +01:00
1c601f0ace * Fri Apr 11 2025 Brian Read <brianr@koozali.org> 11.0.0-76.sme
- Restore css for roundcube embedded  [SME: 12987]
2025-04-11 07:09:03 +01:00
cffbe53fb4 * Wed Apr 09 2025 Brian Read <brianr@koozali.org> 11.0.0-75.sme
- Move review configuration to behind login [SME: 12984]
- Fix crash in port forwarding [SME: 12985]
2025-04-09 10:43:14 +01:00
aad1a458f4 * Wed Mar 26 2025 Brian Read <brianr@koozali.org> 11.0.0-74.sme
- Fix error message and success message format in Local Networking panel [SME: 12969]
2025-03-26 08:58:32 +00:00
252bf20410 * Tue Mar 25 2025 Brian Read <brianr@koozali.org> 11.0.0-73.sme
- Some changes to error message format in css.
- Fix DB Cache problem with port forwarding panel [SME: 12970]
- Fix error and success message display for port forwarding panel [SME: 12969]
2025-03-25 15:05:34 +00:00
ebbe7af9a7 * Mon Mar 24 2025 Brian Read <brianr@koozali.org> 11.0.0-72.sme
- Remove css files from template structure [SME: 12967]
- Rationalise and merge css files
- Adjust some gaps around panels
- Remove HR lines
2025-03-24 17:23:02 +00:00
36de44fcef * Thu Mar 20 2025 Brian Read <brianr@koozali.org> 11.0.0-71.sme
- Sort out navigation menu error on startup [SME: 12946]
- More places where floating panel needed
- Adjust floating panel to make space around it the same
- clean up some css
2025-03-20 12:15:50 +00:00
750ab7dd11 * Wed Mar 19 2025 Brian Read <brianr@koozali.org> 11.0.0-70.sme
- Re-cast the default theme - use proper koozali logo image, unwind multiple divs
- Enhance responsiveness
- Revert Ibay menu name to Ibays
- Remove legacy SM1 button on header
- Remove "?" access to wiki help on header
2025-03-19 13:45:03 +00:00
77ca17c851 * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-69.sme
- Add a total summary report across all existing logs [SME: 12951]
2025-03-17 15:27:16 +00:00
535d78eacb * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-68.sme
- re-write qmailanalog for postfix [SME: 12951]
- Clean up backup.pm
- Enhance module panel - used by mail log analysis and Licence display
2025-03-17 12:22:38 +00:00
88ee369253 * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-67.sme
- re-write qmailanalog for postfix [SME: 12951]
- Clean up backup.pm
- Enhance module panel - used by mail log analysis and Licence display
2025-03-17 12:20:55 +00:00
5be2152e89 * Mon Mar 17 2025 Brian Read <brianr@koozali.org> 11.0.0-67.sme
- re-write qmailanalog for postfix [SME: 12951]
- Clean up backup.pm
- Enhance module panel - used by mail log analysis and Licence display
2025-03-17 12:08:40 +00:00
63973f2bb4 * Tue Mar 11 2025 Brian Read <brianr@koozali.org> 11.0.0-66.sme
- Move the button for each backup panel to the left to conform to all the other panels.
2025-03-11 17:37:44 +00:00
82ff48e641 * Sun Mar 09 2025 Brian Read <brianr@koozali.org> 11.0.0-65.sme
- Sort out missing hostname on nfs and cifs workstation backup on error [SME: 12948]
2025-03-09 15:38:39 +00:00
c5d863b3a0 * Sat Mar 08 2025 Brian Read <brianr@koozali.org> 11.0.0-64.sme
- Add code to check for boot phase completion [SME: 12953]
2025-03-08 10:45:00 +00:00
4f00dfbdb1 * Thu Mar 06 2025 Brian Read <brianr@koozali.org> 11.0.0-63.sme
- Add boot.svg image to Bug Report panel [SME: 12953]
- Move report template to inside smanager tree
- Add one-off systemd task to create boot.svg run from panel
2025-03-07 15:41:55 +00:00
f9bf8cf064 refine spec comment 2025-03-04 14:36:14 +00:00
4f0617f6c3 * Tue Mar 04 2025 Brian Read <brianr@koozali.org> 11.0.0-62.sme
- Update .lex files to conform to standard english punctuation  [SME: 11809]
2025-03-04 14:18:38 +00:00
4c94d768e2 * Tue Mar 04 2025 Brian Read <brianr@koozali.org> 11.0.0-61.sme
- Arrange for the version in the footer to be suppressed if non admin login  [SME: 12887]
2025-03-04 10:11:38 +00:00
1731f75cba * Thu Feb 27 2025 Brian Read <brianr@koozali.org> 11.0.0-60.sme
- Enhance ssh security wording to mention autoblock in remoteaccess panel  [SME: 8309]
2025-02-27 15:54:27 +00:00
5fe285f9f2 * Thu Feb 27 2025 Brian Read <brianr@koozali.org> 11.0.0-59.sme
- Arrange for Urgent notice to be displayed if date is past Rocky 8 EOL [SME: 12918]
2025-02-27 15:02:05 +00:00
1c93be6e8a * Tue Feb 25 2025 Brian Read <brianr@koozali.org> 11.0.0-58.sme
- re-organise open db placement [SME: 12695]
- Re-arrange parameters to tar to avoid warning message in logs [SME: 12943]
2025-02-26 11:57:22 +00:00
ce96f72726 Finally - re-arrange tar params to avoid warning in logs 2025-02-25 12:25:46 +00:00
0fd7137edd sort out open db placements in routes and re-arrange tar params to avoid warning in logs 2025-02-25 12:22:52 +00:00
d179b06f69 Sort out opendb placement and re-arrange tar parameters to avoid warning in logs 2025-02-25 12:14:12 +00:00
c2427189d5 * Fri Feb 21 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-57.sme
- upgrade validate_password sub to use esmith::util [SME: 12937]
  and deduplicate code
2025-02-21 01:35:33 -05:00
887af04bfe Add in buzilla number to changelog line 2025-02-20 15:45:48 +01:00
34b85b1cde * Thu Feb 20 2025 Brian Read <brianr@koozali.org> 11.0.0-56.sme
- open db in routes for backup controller file  [SME: 12933]
- Fix error handling for pre-backup fail [SME:
2025-02-20 14:35:09 +00:00
a5758b4431 * Tue Feb 18 2025 Brian Read <brianr@koozali.org> 11.0.0-55.sme
- fix public ftp access not showing on panel [SME: 12927]
2025-02-18 16:16:36 +00:00
58aa423089 * Sat Feb 15 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-54.sme
- helper to set default value of select field using protected value [SME: 12923]
2025-02-16 02:28:01 -05:00
c0b4d1f90e * Sat Feb 15 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-53.sme
- helper to set default value of select field using protected value [SME: 12923]
2025-02-15 15:19:04 -05:00
a979d472e8 * Wed Feb 12 2025 Jean-Philippe Pialasse <jpp@koozali.org> 11.0.0-52.sme
- move letsencrypt panel to smeserver-certificates [SME: 12916]
2025-02-12 23:14:38 -05:00
d776f20736 * Mon Feb 10 2025 Brian Read <brianr@koozali.org> 11.0.0-51.sme
- Replace url in call to webmail by browser url rather than system host and domain [SME: 12910]
- Fix up CSS so not inline
- Sort out reveiw panel missing routines from FormMagic [SME: 12907].
2025-02-12 16:31:17 +00:00
128 changed files with 3616 additions and 4500 deletions

View File

@@ -8,12 +8,12 @@ use esmith::Build::CreateLinks qw(:all);
my $mngrdir = '/usr/share/smanager';
# templates to expand
for ( qw( sme_core.css sme_main.css sme_menu.css styles.css ) )
{
templates2events("$mngrdir/themes/default/public/css/$_", qw(
bootstrap-console-save smeserver-manager-update
));
}
#for ( qw( sme_core.css sme_main.css sme_menu.css styles.css ) )
#{
# templates2events("$mngrdir/themes/default/public/css/$_", qw(
# bootstrap-console-save smeserver-manager-update
# ));
#}
templates2events("$mngrdir/conf/srvmngr.conf",
qw( smeserver-manager-update smanager-theme-change smanager-modify bootstrap-console-save ));

View File

@@ -1,250 +0,0 @@
{
$OUT = <<'EOF';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the stylesheet used as the basis for older broswers.
Note that you CANNOT simly add styles here and hope they work. ONLY CSS
level 1 styles should be in this file. Everyting else goes into the other 3
files.
These basic styles ensire that browsers that don't understand the @import
method will still be usable. All modern browsers will use the styles in
sme_main.css, sme_menu.css or sme_header.css depending on the frame in which
the page is found.
*/
/* Default HTML styles */
body {
background: #ffffff;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
border-width: 0;
}
table, tr, td, div, p, form {
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
p {
margin-top: 8px;
margin-bottom: 2px;
}
form {
margin-top: 2px;
margin-bottom: 2px;
}
span {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
.notsmall {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
h1, .h1 {
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333333;
font-size: 18px;
margin-bottom: 4px;
margin-top: 12px;
}
h2, .h2 {
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333333;
font-size: 14px;
margin-bottom: 3px;
margin-top: 12px;
}
h3, .h3 {
font-family: Verdana, Arial, Helvetica, sans-serif;
color: #333333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 12px;
}
h4, .h4 {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-style: italic;
color: #333333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 10px;
}
ol, ul, li {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: normal;
color: black;
}
ul {
list-style-type: circle;
}
/* Core styles for use with sme_header.css*/
body.header {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #cccccc;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
}
.hilightbar {
background-color: #ffc50a;
font-size: 4px;
}
.infobar {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #cccccc;
}
.darkergrey {
color: #666666;
}
td.darkgrey {
background-color: #888888;
}
a.update {
color: red;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #cccccc;
}
/* Core styles for use with sme_menu.css */
body.menu {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #e8f3e1;
}
td.section {
padding-bottom: 2px;
padding-top: 8px;
}
.section {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
font-weight: bold;
background-color: #e8f3e1;
}
a.item {
color: #00008b;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.sl {
color: green;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.alert {
color: red;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
/* Core styles for use with sme_main.css */
body.main {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #ffffff;
color: #000000;
}
td.sme-noborders-label {
font-weight: bold;
width: 33%;
text-align: right;
}
hr.sectionbar {
color: #666666;
background-color: #666666;
height: 1px;
width: 80%;
border: 0;
}
hr.sme-copyrightbar {
color: #dddddd;
background-color: #dddddd;
height: 1px;
width: 100%;
border: 0;
}
.sme-copyright {
color: #777777;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
}
/*These style definitions were found int he old css file (manager.css)
but don't seem to ever be referenced in the code. They're here
for reference.
.centerit {
text-align: center;
}
.highlight {
background: #ffc61e;
}
.subheading {
background: #ffffff;
color: #1e385b;
}
*/
EOF
}

View File

@@ -1,96 +0,0 @@
{
$OUT =<<'HERE';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/*contribs.org styling
*/
body.header {
background: #bee6a2;
}
.hilightbar {
background-color: #ffffff;
}
.infobar {
background-color: #98d36e;
}
a.update {
font-size: 11px;
background: #98d36e;
}
/* Core styles for use with sme_menu.css */
body.menu {
background-color: #e8f3e1;
}
td.section {
background-color: #e8f3e1;
}
a.item {
background: #e8f3e1;
}
a.sl {
background: #e8f3e1;
}
a.alert {
background: #e8f3e1;
}
/* Core Styles for use with sme_main.css */
hr.sectionbar {
color: #8ebe43;
background-color: #8ebe43;
}
hr.sme-copyrightbar {
color: #8ebe43;
background-color: #8ebe43;
}
/* flag container*/
#flag-container span {
font-size: 24px;
display: flex; /* Allows for easy centering */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
width: 100%; /* Full width of parent */
height: 24px; /* Set a fixed height */
border: 1px solid #ccc; /* Light gray border */
border-radius: 5px; /* Rounded corners */
cursor: default; /* Prevent text cursor */
}
.fallback-box {
display: inline-block; /* Make it inline-block to fit around the content */
border: 2px solid gray; /* Change the border color as desired */
padding: 10px; /* Add some padding */
border-radius: 10px; /* Round the corners of the box */
font-size: 60px; /* Adjust size if needed */
margin-top: 10px; /* Add some margin */
text-align: center; /* Center text inside the box */
}
HERE
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -1,440 +0,0 @@
{
$OUT = <<'EOF';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the stylesheet used in the main panels only.
This file inherits the styles use in sme_core in the "header" section, and
as noted in the code below. Note that some of the styles here are empty.
This is because the style definition has moved safely to sme_core.css
and the placeholder is left here for reference or future use.
There are a lot of styles in here, so read carefully. Each one is documented.
Styles that were in the old stylesheets, but are not used in the UI are at the
bottom, commented out. These can be removed at the end of the 6.0 cycle */
/* general page properties */
body, body.main {
margin-top: 5px;
margin-right: 20px;
margin-bottom: 5px;
margin-left: 5px;
}
/* Table properties ****************************************/
/* There are THREE types of tables
1. *.sme-layout* is used for layout purposes. It is the "master
container" on a page. It controls the top-level table
inside of which everything else is put.
2. *.sme-noborders* is used for layout, and defines a borderless table and
cells used within it.
2. *.sme-border* is used for tabular data, and defines a header row and borders
for tables that need borders
*/
/*First, some defaults */
td {
text-align: left;
}
/*
sme-layout* : Used for top-level layout
*/
table.sme-layout {
border-collapse: collapse;
margin-bottom: 2px;
margin-top: 2px;
}
tr.sme-layout {
border: 1px solid #dddddd;
}
td.sme-layout {
border: 1px solid #dddddd;
}
/*This special style is actually used only for the button row along the bottom of each page*/
th.sme-layout {
border: 1px solid #dddddd;
background-color: #e8f3e1;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 9pt;
font-weight: bold;
color: #000000;
text-align: right;
padding: 4px;
}
/*
sme-noborders* : Used for mid-level layout
*/
table.sme-noborders {
padding: 0px;
margin-top: 0px;
margin-bottom: 20px;
margin-left: 0px;
margin-right: 0px;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
td.sme-noborders-label {
font-weight: bold;
/*width: 250px;*/
text-align: right;
/*vertical-align: top;*/
background-color: #e8f3e1;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
td.sme-noborders-content {
text-align: left;
vertical-align: top;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
}
td.sme-noborders-info, div.sme-noborders-info {
text-align: left;
vertical-align: top;
}
/* Used for a left-most column of radio buttons (see date/time panel) */
td.sme-radiobutton {
width: 30px;
}
/*
sme-border* : Used for tabular data
*/
table.sme-border {
border-collapse: collapse;
border: 2px solid #cccccc;
empty-cells: show;
margin: 5px 5px 5px 2px;
}
td.sme-border,
td.sme-border-warning,
td.sme-border-right,
td.sme-border-center {
border: 1px solid #cccccc;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: normal;
color: #000000;
text-align: left;
padding-left: 2px;
padding-right: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
td.sme-border-warning {
color: red;
}
td.sme-border-right {text-align: right;}
td.sme-border-center {text-align: center;}
th.sme-border {
border: 1px solid #cccccc;
background-color: #bee6a2;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: bold;
color: #000000;
text-align: center;
vertical-align: bottom;
padding-left: 2px;
padding-right: 2px;
padding-left: 3px;
padding-right: 3px;
padding-top: 3px;
padding-bottom: 3px;
/*border-width: 1px;
border-style: solid;
border-color: #F2F0EE #75736E #75736E #F2F0EE ;*/
}
td.sme-border a, td.sme-border-right a, td.sme-border-center a {
font-size: 10px;
}
/* misc layout stuff*/
/* these two are for any error messages that pop up*/
div.error, div.sme-error, span.error, span.sme-error {
color: red;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: red ;
padding: 2px;
margin-left: 20px;
margin-right: 20px;
margin-top:0px;
margin-bottom:0px;
}
div.error-noborders, div.sme-error-noborders,
span.error-noborders, span.sme-error-noborders
{
color: red;
background-color: #ffffff;
border-width: 0px;
}
div.error h2, span.error h2,
div.error p, span.error p
{
color: red;
}
/* These are for the special case of a link being inside an error message */
div.sme-error a, div.error a, span.error a, span.sme-error a,
div.error-noborders a, div.sme-error-noborders a,
span.error-noborders a, span.sme-error-noborders a
{
color: #ff0000;
font-weight: bold;
text-decoration: underline;
}
/* For when a link is the error message */
a.error:link, a.error:visited, a.error:hover, a.error:active {
color: #ff0000;
font-weight: normal;
text-decoration: underline;
}
/* these two are for any success messages that pop up*/
div.success, span.success {
color: #006400;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: #006400 ;
padding: 2px;
margin-left: 20px;
margin-right: 20px;
margin-top:0px;
margin-bottom:0px;
}
/* These two are for the special case of a link being inside a success message */
div.success a, span.success a
{
color: #006400;
font-weight: bold;
text-decoration: underline;
}
div.success h2, span.success h2,
div.success p, span.success p
{
color: green;
}
/*These two define the copyright footer styles, one for the line and one for the text*/
hr.sme-copyrightbar {
}
.sme-copyright {
}
/* These ones define styles for the links that are made to look like
standard form submit buttons */
a.button-like:link,
a.button-like:visited,
a.button-like:hover,
a.button-like:active,
a.button-like-small:link,
a.button-like-small:visited,
a.button-like-small:hover,
a.button-like-small:active {
font-family: sans-serif;
font-size: 13px;
color: black;
background: #D4D0C8;
text-decoration: none;
text-align: left;
border-color: #F2F0EE #75736E #75736E #F2F0EE ;
margin-top: 10px;
margin-right: 2px;
margin-bottom: 10px;
margin-left: 2px;
border-style: solid;
border-top-width: 2px;
border-right-width: 2px;
border-bottom-width: 2px;
border-left-width: 2px;
padding-top: 2px;
padding-bottom: 2px;
padding-left: 6px;
padding-right: 6px;
}
a.button-like-small:link,
a.button-like-small:visited,
a.button-like-small:hover,
a.button-like-small:active {
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
font-size: 10px;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 1px;
padding-right: 1px;
}
a.button-like:active,
a.button-like-small:active {
border-color: #75736E #F2F0EE #F2F0EE #75736E ;
}
/* EXPERIMENTAL SECTION */
/* These are styles used to experiment with. */
/* class for links, similar to the class in sme_menu.css, but for a red button */
a.button-like-red:link,
a.button-like-red:visited,
a.button-like-red:hover,
a.button-like-red:active {
border-left: #F1726C 2px solid;
border-right: #B42025 2px solid;
border-top: #F1726C 2px solid;
border-bottom: #B42025 2px solid;
}
a.button-like-red:active {
border-color: #75736E #F2F0EE #F2F0EE #75736E ;
}
/*These are style definitions found in the UI but not defined in any file I
could locate. They're listed here for historical purposes, but have been
removed from the UI
pagedescription (used in the first paragraph of text on a page) [HTML.pm]
label (used in forms) [HTML.pm]
field (used in forms) [HTML.pm]
fielddescription (used ???)[HTML.pm]
buttons (used in forms) [HTML.pm]
*/
/*td.sme-submitbutton {
text-align: right;
}
*/
/*These style definitions were found int he old css file (manager.css)
but don't seem to ever be referenced in the code. They're here
for reference.
.banner {
background: #000000;
color: #ffffff;
}
.banner-right {
font-family: Verdana, Arial, Helvetica, sans-serif;
background: #e17200;
color: #ffffff;
}
.border {
background: #000000;
color: #000000;
border-color: #000000;
}
.sidebar {
width: 200px;
background: #ffffff;
font-size: smaller;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: normal;
}
.sidebar-title {
background: #1e385b;
color: #ffffff;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
}
.newsitem {
background: #ffffff;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
margin-bottom: 5px;
}
.newsitem-title {
background: #cccccc;
color: #ffffff;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
}
.newsitem-footer {
background: #cccccc;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: smaller;
text-align: right;
}
.newsitem-detail {
font-size: smaller;
font-weight: normal;
}
.formlabel {
background: #c0c0c0;
color: #000000;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: small;
font-weight: bold;
text-align: right;
}
.welcome-link {
background: #ffffff;
color: #1e385b;
}
.littlelink {
font-family: Verdana, Arial, Helvetica, sans-serif;
}
#textlayer {
position: absolute;
visibility: inherit;
top: 160px;
left: 50px;
z-index: 2;
}
#para {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
color: #000000;
}
#title {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-weight: bold;
padding: 7px 7px 7px 7px;
color: #ffffff;
}
*/
EOF
}

View File

@@ -1,50 +0,0 @@
{
$OUT =<<'HERE';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/*contribs.org styling */
/* This special style is actually used only for the button row along the bottom of each page */
th.sme-layout {
border: 1px solid #8ebe43;
background-color: #bee6a2;
}
table.sme-border {
border: 2px solid #dddddd;
}
td.sme-border-warning,
td.sme-border-right,
td.sme-border-center {
border: 1px solid #dddddd;
}
td.sme-border-right {text-align: right;}
td.sme-border-center {text-align: center;}
th.sme-border {
border: 1px solid #dddddd;
background-color: #e8f3e1;
}
HERE
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -1,229 +0,0 @@
{
$OUT = <<'EOF';
/* from e-smith-manager to smanager (smeserver_manager2) */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the stylesheet used in the navigation panel only
This file inherits the styles use in sme_core in the "navigation" section,
and as noted in the code below. Note that some of the styles here are empty.
This is because the style definition has moved safely to sme_core.css and
the placeholder is left here for reference or future use.
There are a lot of styles in here, so read carefully. Each one is
documented.
Styles that were in the old stylesheets, but are not used in the UI are at
the bottom, commented out. These can be removed at the end of the 6.0
cycle */
/* Sets the general page properties */
body, body.menu {
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 2px;
}
/* This is the section heading style */
.section {
}
td.menu-cell {
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
padding-bottom: 0px;
}
/*
All the a links use pseudoclasses to control the two visual link styles.
For example:
a.item:link the general link item
a.item-current:link: the active link item
The switch from item to item-current is done with a javascript script in the head of the
navigation page, using the onClick event.
We are making heavy use of the cascade with these.
*/
/* a:link controls the look of a link when the mouse is nowhere near it */
a.item:link, a.item-current:link,
a.warn:link, a.warn-current:link {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
text-align: left;
border-color: #e8f3e1;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-top: 0px;
padding-bottom: 2px;
}
/* a:visited controls the look of a visited link (one that has been clicked) */
a.item:visited, a.item-current:visited,
a.warn:visited, a.warn-current:visited {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
border-color: #e8f3e1;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/* a:hover controls the look of a link under the curser*/
a.item:hover, a.item-current:hover,
a.warn:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #cccccc;
border-color: #888888;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/* a:active controls the look of a link as it is selected*/
a.item:active, a.item-current:active,
a.warn:active, a.warn-current:active {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: white;
background: black;
text-decoration: none ;
border-color: #000000;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/*
These styles are to ensure that a selected link appears selected, even if the link
opens in another frame. This uses a javascript chunk in the head of the navigation
frame to change the style using the onClick event.
*/
a.item-current:link, a.warn-current:link,
a.item-current:visited, a.warn-current:visited,
a.item-current:active, a.warn-current:active,
a.item-current:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #ffffff;
border-color: #888888;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
border-style: solid;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
/* these two add a border on the styles defined directly above when
the mouse is hovering over them */
a.item-current:hover, a.warn-current:hover {
border-color: #888888;
}
/* These redefine a few elements to make room for the icon to the left of the warn class*/
a.warn:link, a.warn-current:link,
a.warn:visited, a.warn-current:visited,
a.warn:active, a.warn-current:active,
a.warn:hover, a.warn-current:hover {
background-image: url(/server-common/warn.gif);
background-repeat: no-repeat;
background-position: 10px;
padding-left: 25px;
}
/*end*/
EOF
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -1,281 +0,0 @@
{
$OUT = <<'EOF';
/* smeserver_manager2 */
/*----------------------------------------------------------------------
* copyright (C) 1999-2003 Mitel Networks Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Technical support for this program is available from Mitel Networks
* Please visit our web site www.mitel.com for details.
*----------------------------------------------------------------------
*/
/* This is the basic stylesheet originally used in the mojo version.
*/
body{
background-color: #FFF;
}
#container{
max-width: 100%;
position: relative;
margin: auto;
}
#navigation{
width: 190px;
position: absolute;
margin-left: 0px;
padding: 5px;
background-color: #E8F3E1;
/* height: 600px; */
overflow: auto;
}
#main{
margin-left: 195px;
padding: 10px;
}
#central{
margin-left: 0px;
padding: 5px;
}
#footer{
margin-left: 0px;
padding: 5px;
}
#header {
background: #bee6a2;
}
#header h1, a:link, a:visited {
color: black;
text-decoration: none;
/* contribs.org styling */
}
a:link { color: #006921; text-decoration: none; }
a:visited { color: #063; text-decoration: none; }
a:hover { color: #F00; text-decoration: none; }
a:active { color: #606060; text-decoration: none; }
.sme-error {
color: red;
display:block;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: red ;
padding: 2px;
margin-left: 10px;
margin-right: 10px;
margin-top:0px;
margin-bottom:0px;
}
.sme-warning {
color: orange;
display:block;
background-color: #ffffff;
border-width: 1px;
border-style: solid;
border-color: orange ;
padding: 4px;
margin-left: 20px;
margin-right: 20px;
margin-top:2px;
margin-bottom:2px;
}
#footer img {
float: right;
position: fixed;
margin-left: 40%;
}
label.field-with-error {
color: #dd7e5e
}
input.field-with-error {
background-color: #fd9e7e
}
span.label {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1; /*lightgreen;*/
width: 30%;
text-align: right;
}
td.label {
font-weight: bold;
background-color: #e8f3e1; /*lightgreen;*/
width: 30%;
text-align: right;
}
span.label2 {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1; /*lightgreen;*/
text-align: right;
}
span.data {
padding: 2px;
font-weight: bold;
margin-left: 0%;
/* background-color: lightblue;*/
}
span.data2 {
padding: 2px;
/* background-color: lightblue; */
}
input.action {
margin-left: 0px;
background-color: #bee6a2; /*lightgreen;*/
color: darkgreen;
border-radius: 8px;
border: 2px solid #4CAF50; /* Green */
display: flex;
justify-content: center;
align-items: center;
}
input.action:hover {background-color: #3e8e41; color:white;}
input.action:active {
background-color: #3e8e41;
transform: translate(-2px,2px);
}
.center {
display: flex;
justify-content: center;
}
input.action2 {
margin-left: 0px;
color: black;
background-color: #d4d0c8;
display: flex;
justify-content: center;
}
#modul.desc {
padding: 3px;
background-color: grey;
}
[type = 'text'] {
margin-left: 0px;
/*background-color: lightblue;*/
}
.a, .return {
color: #661866;
font-weight: bold;
}
a.section {
}
.a, .item {
line-height: 12px;
}
a.section-title {
display: inline-block;
color: #6CA345; /*#888;*/
padding-left: 5px;
padding-right: 5px;
line-height: 18px;
font-weight: bold;
}
a.menu-title {
display: inline-block;
color: #1A6D1A; /*#666;*/
padding-left: 1px;
padding-right: 1px;
font-weight: bold;
}
#module {
/* height: 600px; */
overflow: auto;
}
#h2l1 {
height: 40px;
width: 100%;
}
#h2e11 {
width: 50%;
float: left;
}
#h2e12 {
background-color: #C0E7A6;
float: left;
text-align: right;
}
#h2l2 {
/* background-color: #A8F9E7;*/
border-top: solid white 3px;
border-bottom: solid white 2px;
height: 14px;
width: 100%;
padding: 1px;
}
#h2e21 {
float: left;
width: 70%;
}
#h2e22,#h2e23,#h2e12 {
float: left;
width: 14em;
text-align: center;
}
.toggle-password {
margin-left: -30px;
}
.tg-icon {
position: relative;
top: 5px;
left: 2px;
}
/*end*/
EOF
}

View File

@@ -1 +0,0 @@
/* DO NOT MODIFY THIS FILE! It is updated automatically */

View File

@@ -0,0 +1,9 @@
[Unit]
Description=Koozali SME Server boot diagnostic tool
After=sme-server.target
PartOf=sme-server.target
[Service]
Type=oneshot
ExecStart=/bin/sh -c "/usr/bin/systemd-analyze plot > /usr/share/smanager/themes/default/public/images/boot.svg"
RemainAfterExit=yes

View File

@@ -4,6 +4,7 @@ package SrvMngr;
use strict;
use warnings;
use utf8;
binmode(STDOUT);
use Mojo::Base 'Mojolicious';
@@ -29,9 +30,14 @@ use SrvMngr::Model::Main;
use SrvMngr::Plugin::WithoutCache;
use esmith::I18N;
use esmith::ConfigDB::UTF8;
use esmith::NavigationDB; # no UTF8 raw is ok for ASCII only flat file
# Import the function(s) you need
use SrvMngr_Auth qw(check_admin_access);
#this is overwrittrn with the "release" by the spec file - release can be "99.el8.sme"
our $VERSION = '50.el8.sme';
our $VERSION = '94.el8.sme';
#Extract the release value
if ($VERSION =~ /^(\d+)/) {
$VERSION = $1; # $1 contains the matched numeric digits
@@ -43,10 +49,10 @@ $VERSION = eval $VERSION;
use Exporter 'import';
our @EXPORT_OK = qw(
init_session get_mod_url theme_list
getNavigation ip_number is_normal_password email_simple
getNavigation ip_number validate_password is_normal_password email_simple
mac_address_or_blank mac_address ip_number_or_blank
lang_space get_routes_list subnet_mask get_reg_mask
gen_locale_date_string get_public_ip_address
gen_locale_date_string get_public_ip_address simpleNavMerge
);
has home => sub {
@@ -212,6 +218,22 @@ sub setup_helpers {
Mojo::JWT->new(secret => shift->app->secrets->[0] || die)
});
$self->helper( selected_field => sub {
my $self = shift;
my @options = shift;
my $selected = shift;
my $count = 0;
# search for occurence of value $selected in arrays; if found add selected => 'selected'
for (my $i = 0; $i <= $#{$options[0]} ; $i++){
if (grep /^$selected$/, @{$options[0][$i]}) {
push( @{$options[0][$i]} ,'selected', 'selected' );
$count++;last;
}
}
push ( @{$options[0]} ,[ ucfirst( $selected), $selected, 'selected', 'selected'] ) if ($count <1);
return @options;
});
}
@@ -285,10 +307,11 @@ sub setup_routing {
$if_logged_in->get('/userpassword')->to('userpassword#main')->name('passwd');
$if_logged_in->post('/userpassword')->to('userpassword#change_password')->name('passwd2');
my $if_admin = $r->under( sub {
my $c =shift;
return $c->is_admin || $c->auth_fail($c->l("acs_ADMIN"));
});
my $if_admin = $r->under( sub {
my $c = shift;
# Call the imported function directly
return check_admin_access($c) || $c->auth_fail($c->l("acs_ADMIN"));
});
$if_admin->get('/backup')->to('backup#main')->name('backup');
$if_admin->post('/backup')->to('backup#do_display')->name('backupd');
@@ -303,7 +326,10 @@ sub setup_routing {
$if_admin->post('/clamav')->to('clamav#do_update')->name('clamav2');
$if_admin->get('/datetime')->to('datetime#main')->name('datetime');
$if_admin->post('/datetime')->to('datetime#do_update')->name('datetime2');
$if_admin->post('/datetimeu')->to('datetime#do_update')->name('datetimeu');
$if_admin->get('/datetimed')->to('datetime#do_display')->name('datetimed');
$if_admin->post('/datetimet')->to('datetime#do_testntp')->name('datetimet');
$if_admin->get('/directory')->to('directory#main')->name('directory');
$if_admin->post('/directory')->to('directory#do_update')->name('directory2');
@@ -398,28 +424,59 @@ sub setup_routing {
# additional routes (for contribs) got from 'routes' db
#my @routes = @{SrvMngr::get_routes_list()};
foreach (@{SrvMngr::get_routes_list()}) {
if ( defined $_->{method} and defined $_->{url} and defined $_->{ctlact} and defined $_->{name} ) {
my $menu = defined $_->{menu} ? $_->{menu} : 'A';
if ( $menu eq 'N' ) {
$r->get($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'get');
$r->post($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'post');
} elsif ( $menu eq 'U' ) {
$if_logged_in->get($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'get');
$if_logged_in->post($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'post');
} else {
$if_admin->get($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'get');
$if_admin->post($_->{url})->to($_->{ctlact})->name($_->{name})
if ( $_->{method} eq 'post');
}
#foreach (@{SrvMngr::get_routes_list()}) {
#if ( defined $_->{method} and defined $_->{url} and defined $_->{ctlact} and defined $_->{name} ) {
#my $menu = defined $_->{menu} ? $_->{menu} : 'A';
#if ( $menu eq 'N' ) {
#$r->get($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'get');
#$r->post($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'post');
#} elsif ( $menu eq 'U' ) {
#$if_logged_in->get($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'get');
#$if_logged_in->post($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'post');
#} else {
#$if_admin->get($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'get');
#$if_admin->post($_->{url})->to($_->{ctlact})->name($_->{name})
#if ( $_->{method} eq 'post');
#}
#}
#}
foreach my $route (@{SrvMngr::get_routes_list()}) {
if (defined $route->{method} && defined $route->{url} && defined $route->{ctlact} && defined $route->{name}) {
my $menu = defined $route->{menu} ? $route->{menu} : 'A';
# Fix controller case: convert "ControllerName" to "controllername" in "ControllerName#action"
# this is so that AdminLTE breadcrumb works - it appears that perl Packages names are NOT case sensitive
# and that the breadcrumb package assumes that the package name is the same as the main route.
my ($controller, $action) = split /#/, $route->{ctlact}, 2;
my $fixed_ctlact = lc($controller) . '#' . $action;
if ($menu eq 'N') {
$r->get($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'get';
$r->post($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'post';
}
elsif ($menu eq 'U') {
$if_logged_in->get($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'get';
$if_logged_in->post($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'post';
}
else { # Default: menu 'A'
$if_admin->get($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'get';
$if_admin->post($route->{url})->to($fixed_ctlact)->name($route->{name})
if $route->{method} eq 'post';
}
}
}
}
$if_admin->get('/config/:key' => {key => qr/[a-z0-9]{2,32}/})->to('request#getconfig')->name('getconfig');
$if_admin->get('/account/:key' => {key => qr/[a-z0-9]{2,32}/})->to('request#getaccount')->name('getaccount');
@@ -530,12 +587,10 @@ sub theme_list {
#------------------------------------------------------------
sub getNavigation {
use esmith::NavigationDB;
my $c = shift;
my $class = shift; #not the controller as it is called as an external, not part of the controller.
my $lang = shift || 'en-us';
my $menu = shift || 'N';
my $username = shift || ''; #Username when logged in as a user not admin
# my $lang = $c->session->{lang} || 'en-us';
@@ -544,13 +599,33 @@ sub getNavigation {
my @files = ();
my %files_hash = ();
# Added: Store allowed admin panels for non-admin users
my @allowed_admin_panels = ();
my $is_admin = 1; # Default to admin (full access)
# Added: Check if user is non-admin and get their allowed panels
if ($username ne '') {
# Get the AccountsDB to check user permissions
my $accountsdb = esmith::AccountsDB::UTF8->open_ro() or
die "Couldn't open AccountsDB\n";
# Check if user has AdminPanels property
my $user_rec = $accountsdb->get($username);
if (defined $user_rec && $user_rec->prop('AdminPanels')) {
$is_admin = 0; # User is non-admin with specific panel access
# Get comma-separated list of allowed admin panels
my $admin_panels = $user_rec->prop('AdminPanels');
@allowed_admin_panels = split(/,/, $admin_panels);
}
}
#-----------------------------------------------------
# Determine the directory where the functions are kept
#-----------------------------------------------------
my $navigation_ctlr_ignore =
"(\.\.?|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm|Legacypanel\.pm(-.*)?)";
# "(\.\.?|Initial\.pm|Manual\.pm|Swttheme\.pm|Request\.pm|Modules\.pm(-.*)?)";
"(\.\.?|.*\-Custom\.pm|Swttheme\.pm|Login\.pm|Request\.pm|Modules\.pm|Legacypanel\.pm(-.*)?)";
# "(\.\.?|Initial\.pm|.*Manual\.pm|Swttheme\.pm|Request\.pm|Modules\.pm(-.*)?)";
my $navigation_cgi_ignore =
"(\.\.?|navigation|noframes|online-manual|(internal|pleasewait)(-.*)?)";
@@ -605,8 +680,7 @@ sub getNavigation {
my $navinfo = NAVIGATIONDIR . "/navigation.$lang";
my $navdb = esmith::NavigationDB->open_ro( $navinfo ) or
die "Couldn't open $navinfo\n";
my $navdb = esmith::NavigationDB->open_ro( $navinfo ) or die "Couldn't open $navinfo\n"; # no UTF8
# Check the navdb for anything with a UrlPath, which means that it doesn't
# have a cgi file to be picked up by the above code. Ideally, only pages
@@ -622,70 +696,110 @@ sub getNavigation {
}
foreach my $file (keys %files_hash)
{
#my $heading = 'Unknown';
my $heading = 'Legacy';
my $description = $file;
my $headingWeight = 99999;
my $descriptionWeight = 99999;
my $urlpath = '';
my $menucat = 'A'; # admin menu (default)
{
#my $heading = 'Unknown';
my $heading = 'Legacy';
my $description = $file;
my $headingWeight = 99999;
my $descriptionWeight = 99999;
my $urlpath = '';
my $menucat = 'A'; # admin menu (default)
my $rec = $navdb->get($file);
my $rec = $navdb->get($file);
if (defined $rec)
{
$heading = $rec->prop('Heading');
$description = $rec->prop('Description');
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
$descriptionWeight = $rec->prop('DescriptionWeight');
$urlpath = $rec->prop('UrlPath') || '';
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
}
next if $menu ne $menucat;
if (defined $rec)
{
$heading = $rec->prop('Heading');
$description = $rec->prop('Description');
$headingWeight = $rec->prop('HeadingWeight') || 99999; #Stop noise in logs if file in dir does not have nav header.
$descriptionWeight = $rec->prop('DescriptionWeight');
$urlpath = $rec->prop('UrlPath') || '';
$menucat = $rec->prop('MenuCat') || 'A'; # admin menu (default)
}
# Added: Check if this is an admin menu item and if user has access
if ($menucat eq 'A' && !$is_admin) {
# Skip this admin panel if user doesn't have access to it
my $has_access = 0;
my $file_no_ext = $file;
$file_no_ext =~ s/\.pm$//; # Remove .pm extension if present
foreach my $allowed_panel (@allowed_admin_panels) {
if ($file_no_ext eq lc($allowed_panel)) {
#die("Here!!$file $file_no_ext $allowed_panel ");
$has_access = 1;
last;
}
}
next if !$has_access;
}
#--------------------------------------------------
# add heading, description and weight information to data structure
#--------------------------------------------------
next if $menu ne $menucat;
unless (exists $nav {$heading})
{
$nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] };
}
#--------------------------------------------------
# add heading, description and weight information to data structure
#--------------------------------------------------
$nav {$heading} {'COUNT'} ++;
$nav {$heading} {'WEIGHT'} += $headingWeight;
unless (exists $nav {$heading})
{
$nav {$heading} = { COUNT => 0, WEIGHT => 0, DESCRIPTIONS => [] };
}
# Check for manager panel, and assign the appropriate
# cgi-bin prefix for the links.
# Grab the last 2 directories by splitting for '/'s and
# then concatenating the last 2
# probably a better way, but I don't know it.
$nav {$heading} {'COUNT'} ++;
$nav {$heading} {'WEIGHT'} += $headingWeight;
my $path;
if ( $files_hash{$file} eq 'ctrl') {
$path = "2";
} elsif ( $files_hash{$file} eq 'cgim') {
$path = "/cgi-bin";
} else {
my @filename = split /\//, $files_hash{$file};
$path = "/$filename[scalar @filename - 2]/$filename[scalar @filename - 1]";
};
# Check for manager panel, and assign the appropriate
# cgi-bin prefix for the links.
# Grab the last 2 directories by splitting for '/'s and
# then concatenating the last 2
# probably a better way, but I don't know it.
push @{ $nav {$heading} {'DESCRIPTIONS'} },
{ DESCRIPTION => $description,
WEIGHT => $descriptionWeight,
FILENAME => $urlpath ? $urlpath : "$path/$file",
CGIPATH => $path,
MENUCAT => $menucat
my $path;
if ( $files_hash{$file} eq 'ctrl') {
$path = "2";
} elsif ( $files_hash{$file} eq 'cgim') {
$path = "/cgi-bin";
} else {
my @filename = split /\//, $files_hash{$file};
$path = "/$filename[scalar @filename - 2]/$filename[scalar @filename - 1]";
};
push @{ $nav {$heading} {'DESCRIPTIONS'} },
{ DESCRIPTION => $description,
WEIGHT => $descriptionWeight,
FILENAME => $urlpath ? $urlpath : "$path/$file",
CGIPATH => $path,
MENUCAT => $menucat
};
}
return \%nav;
}
sub simpleNavMerge {
#Used to merge two nav structures - used for the user and selected admin menu.
my ($class,$nav1, $nav2) = @_;
my %result = %$nav1; # Start with a copy of first nav
# Merge in second nav
foreach my $heading (keys %$nav2) {
if (exists $result{$heading}) {
# Add counts and weights
$result{$heading}{COUNT} += $nav2->{$heading}{COUNT};
$result{$heading}{WEIGHT} += $nav2->{$heading}{WEIGHT};
# Append descriptions
push @{$result{$heading}{DESCRIPTIONS}}, @{$nav2->{$heading}{DESCRIPTIONS}};
} else {
# Just copy the heading
$result{$heading} = $nav2->{$heading};
}
}
return \%result;
}
sub _lang_space {
@@ -733,7 +847,7 @@ sub get_routes_list {
my $c = shift;
my $rtdb = esmith::ConfigDB->open_ro('routes') || die 'Cannot open Routes db';
my $rtdb = esmith::ConfigDB::UTF8->open_ro('routes') || die 'Cannot open Routes db';
my @routes = $rtdb->get_all();
my @rt;
@@ -772,7 +886,23 @@ sub ip_number {
return 'OK';
}
sub validate_password {
my ($c, $strength, $pass) = @_;
use esmith::util;
use POSIX qw(locale_h);
use locale;
my $old_locale = setlocale(LC_ALL);
setlocale(LC_ALL, "en_US");
my $reason = esmith::util::validatePassword($pass,$strength);
return "OK" if ($reason eq "ok");
setlocale(LC_ALL, $old_locale);
return
$c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because") . " "
. $c->l($reason). ".";
} ## end sub validate_password
# to deprecate : this is not anymore a way to validate our passwords
sub is_normal_password {
# from CGI::FormMagick::Validator qw( password );
@@ -799,7 +929,7 @@ sub gen_locale_date_string
sub get_public_ip_address
{
my $self = shift;
my $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
my $cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $sysconfig = $cdb->get('sysconfig');
if ($sysconfig)
{
@@ -812,7 +942,6 @@ sub get_public_ip_address
return undef;
}
sub email_simple {
my ($c, $data) = @_;
@@ -894,4 +1023,4 @@ sub get_reg_mask {
}
1;
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Backup;
#----------------------------------------------------------------------
# heading : System
# description : Backup or restore
# navigation : 4000 200
# navigation : 4000 100
# Copyright (C) 2002 Mitel Networks Corporation
#----------------------------------------------------------------------
# routes : end
@@ -20,22 +20,23 @@ use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number_or_blank);
use Quota;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use esmith::util;
use File::Basename;
use File::Find;
use File::Path qw(make_path remove_tree);
use esmith::Backup;
use esmith::BackupHistoryDB;
use esmith::BackupHistoryDB; #no UTF8 and not in use
use esmith::util;
use esmith::lockfile;
use esmith::BlockDevices;
use constant DEBUG => $ENV{MOJO_SMANAGER_DEBUG} || 0;
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
our $rdb = esmith::ConfigDB->open('/etc/e-smith/restore')
|| die "Couldn't open restore db";
use constant FALSE => 0;
use constant TRUE => 1;
my ($cdb,$adb,$rdb);
my $es_backup = new esmith::Backup or die "Couldn't create Backup object\n";
my @directories = $es_backup->restore_list;
@directories = grep { -e "/$_" } @directories;
@@ -52,6 +53,9 @@ sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %bac_datas = ();
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$rdb = esmith::ConfigDB::UTF8->open('/etc/e-smith/restore');
my $title = $c->l('bac_BACKUP_TITLE');
my $notif;
$bac_datas{'function'} = 'desktop_backup';
@@ -108,6 +112,9 @@ sub do_display {
my $rt = $c->current_route;
my ($res, $result) = '';
my $function = $c->param('Function');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$rdb = esmith::ConfigDB::UTF8->open('/etc/e-smith/restore');
if ($function =~ /^(\S+)$/) {
$function = $1;
@@ -129,7 +136,11 @@ sub do_display {
$c->stash(compressionlevel => $CompressionLevel, exclude => \@exclude, directories => \@directories);
# streaming download in template
return $c->render("/backdown");
$c->render(template=>"backdown");
#sleep(30);
# Redirect to the front page
#$c->redirect_to('/backup');
return ""
} ## end if ($function eq 'desktop_backup')
if ($function eq 'tape_configure') {
@@ -265,6 +276,9 @@ sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$rdb = esmith::ConfigDB::UTF8->open('/etc/e-smith/restore');
my $function = $c->param('Function');
DEBUG && warn("do_update $function");
my %bac_datas = ();
@@ -513,13 +527,13 @@ sub do_update {
# common part for all functions
if ($res ne 'OK') {
if ($res eq 'NEXT') {
$dest = 'back_' . $bac_datas{"function"};
} else {
$c->stash(error => $result);
$dest = "back_$function";
}
$bac_datas{vfstype} = $c->param('VFSType');
$c->stash(title => $title, bac_datas => \%bac_datas);
return $c->render($dest);
} ## end if ($res ne 'OK')
@@ -919,7 +933,7 @@ sub workstnVerify {
sub workstnRestore {
my ($c) = @_;
my $out;
my $out = '';
my $restoreref = $c->param('Backupset');
my $set = $restoreref;
$set =~ s/\/[^\/]*$//;
@@ -1002,6 +1016,7 @@ sub workstnRestore {
return "$c->l('bac_OPERATION_STATUS_REPORT') $c->l('bac_ERR_PRE_RESTORE')";
}
$| = 1;
my $RD;
if (open(RD, "-|")) {
@@ -1034,8 +1049,8 @@ sub workstnRestore {
or warn($c->l('bac_ERR_RESTORING_INITIAL_GRP') . "\n");
esmith::util::backgroundCommand(0, "/sbin/e-smith/signal-event", "post-upgrade");
# system("/sbin/e-smith/signal-event", "post-upgrade") == 0
# or die ($c->l('bac_ERROR_UPDATING_CONFIGURATION')."\n");
#system("/sbin/e-smith/signal-event", "post-upgrade") == 0
# or die ($c->l('bac_ERROR_UPDATING_CONFIGURATION')."\n");
} else {
$message = $c->l('bac_RESTORE_FAILED');
}
@@ -1063,9 +1078,111 @@ sub workstnRestore {
die($error_message) if $error_message;
exit(0);
} ## end else [ if (open(RD, "-|")) ]
$rdb->reload;
$error_message .= $c->bunmount($mntdir, $VFSType);
return '#OK#' . $out;
#my $RD;
## Fork-safe open with explicit error handling
#unless (open($RD, "-|")) {
## Child process
#local $SIG{__DIE__} = sub { exit 255 };
#$| = 1; # Autoflush
#eval {
#foreach my $file (@restorefiles) {
## Security: strict filename validation
#unless ($file =~ m{^[\w\/.-]+$}) {
#die "Invalid filename: $file";
#}
## Check file existence
#unless (-e $file) {
#die "Backup file $file does not exist";
#}
## Execute dar with error checking
#system("/usr/bin/dar", "-Q", "-x", $file, "-v", "-N", "-R", "/", "-wa");
#if ($? == -1) {
#die "Failed to execute dar: $!";
#} elsif ($? & 127) {
#die sprintf("dar died with signal %d, %s coredump",
#($? & 127), ($? & 128) ? 'with' : 'without');
#} elsif ($? >> 8 != 0) {
#die "dar exited with error code " . ($? >> 8);
#}
#}
## Unmount with error checking
#if (my $unmount_err = $c->bunmount($mntdir, $VFSType)) {
#die "Unmount failed: $unmount_err";
#}
#};
#if (my $child_err = $@) {
#print STDERR "CHILD ERROR: $child_err";
#exit 254;
#}
#exit 0;
#}
#else {
## Parent process
#eval {
## Verify fork succeeded
#unless (defined $RD) {
#die "Fork failed: $!";
#}
#$out .= $c->l('bac_FILES_HAVE_BEEN_RESTORED') . "\n<UL>";
#my $complete = 0;
## Read from child process
#while (<$RD>) {
#$complete++ if /etc\/samba\/smbpasswd$/;
#$out .= "<li>$_</li>\n";
#}
#$out .= "</UL>";
## Close pipe and check status
#unless (close $RD) {
#die "Pipe close failed: $!";
#}
#my $child_status = $?;
#if ($child_status != 0) {
#die "Child process failed with status " . ($child_status >> 8);
#}
## Post-restore actions
#if ($complete) {
#system("/usr/sbin/groupmod", "-g", $www_gid, "www");
#if ($? != 0) {
#die $c->l('bac_ERR_RESTORING_GID') . ": $! (status $?)";
#}
#system("/usr/sbin/usermod", "-g", $www_gid, "www");
#if ($? != 0) {
#die $c->l('bac_ERR_RESTORING_INITIAL_GRP') . ": $! (status $?)";
#}
#my $bg_result = esmith::util::backgroundCommand(0, "/sbin/e-smith/signal-event", "post-upgrade");
#unless ($bg_result) {
#die "Failed to schedule post-upgrade event";
#}
#} else {
#die $c->l('bac_RESTORE_FAILED');
#}
#};
## Error handling
#if (my $err = $@) {
#$rec->set_prop('state', 'failed');
#$rec->set_prop('error', "$err");
#esmith::lockfile::UnlockFile($file_handle);
#return $c->l('bac_RESTORE_FAILED_MSG') . ": $err";
#}
#}
$rdb->reload;
$error_message .= $c->bunmount($mntdir, $VFSType);
return '#OK#' . $out;
} ## end sub workstnRestore
sub workstnSelRestore() {
@@ -1442,6 +1559,7 @@ sub performReboot {
#print "$c->l('bac_SERVER_REBOOT')";
#print "$c->l('bac_SERVER_WILL_REBOOT')";
warn "reboot coming";
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "reboot");
return "#OK#" . $c->l('bac_SERVER_WILL_REBOOT');
} ## end sub performReboot
@@ -1847,7 +1965,7 @@ sub showSize {
} ## end sub showSize
sub desktopBackupRecordStatus {
my ($backup, $phase, $status) = @_;
my ($c,$backup, $phase, $status) = @_;
my $now = time();
warn("Backup terminated: $phase failed - status: $status\n");
$backup->set_prop('EndEpochTime', "$now");
@@ -1972,7 +2090,7 @@ sub bunmount {
system('/bin/umount', '-f', $mount) == 0
or return ($c->l('bac_ERR_WHILE_UNMOUNTING'));
}
return;
return "";
} ## end sub bunmount
sub findmnt {

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Bugreport;
#----------------------------------------------------------------------
# heading : Investigation
# description : Report a bug
# navigation : 7000 500
# navigation : 7000 300
# routes : end
#------------------------------
use strict;
@@ -15,7 +15,11 @@ use SrvMngr qw(theme_list init_session);
use Text::Template;
use File::Basename;
use SrvMngr qw( gen_locale_date_string );
our $cdb = esmith::ConfigDB->open or die "Couldn't open ConfigDB\n";
use esmith::ConfigDB::UTF8;
our $cdb = esmith::ConfigDB::UTF8->open or die "Couldn't open ConfigDB\n";
use constant FALSE => 0;
use constant TRUE => 1;
# Get some basic info on the current SME install
our $sysconfig = $cdb->get('sysconfig');
@@ -78,7 +82,7 @@ sub create_configuration_report {
# create the reporting template
my $configreport_template = Text::Template->new(
TYPE => 'FILE',
SOURCE => '/etc/e-smith/web/common/configuration_report.tmpl',
SOURCE => '/usr/share/smanager/themes/default/public/configuration_report.tmpl',
UNTAINT => 1
);
my $report_creation_time = gen_locale_date_string;
@@ -114,13 +118,40 @@ sub create_configuration_report {
# prcess template
my $result = $configreport_template->fill_in(HASH => \%vars);
#take out any multiple blank lines
#$result =~ s/\n{3,}/\n/g;
# write processed template to file
open(my $cfgrep, '>', $configreportfile) or die "Could not create temporary file for config report!";
print $cfgrep $result;
close $cfgrep;
#check if boot phase has completed.
if (wait_for_boot_completion()) {
#And create boot analysis image - now run externally following boot.
$result = `/usr/bin/systemctl start bootsequence.service`;
if (!$? == 0) {
warn "/usr/bin/systemd-analyze plot Command failed \n";
}
}
} ## end sub create_configuration_report
sub wait_for_boot_completion {
my $timeout = 60; # 1-minute timeout
my $end_time = time() + $timeout;
while (time() < $end_time) {
if (`systemctl list-jobs 2>&1` =~ /No jobs running/) {
return TRUE; # Success
}
sleep 5;
}
warn "Boot did not complete within $timeout seconds.\n";
return FALSE; # Failure
} ## end wait_for_boot_completion
sub show_config_report {
my $c = shift;
my $out = '';

View File

@@ -13,9 +13,9 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB::UTF8;
#package esmith::FormMagick::Panel::clamav;
our $db = esmith::ConfigDB->open() || die "Couldn't open config db";
our $db;
sub main {
my $c = shift;
@@ -23,6 +23,7 @@ sub main {
my %clm_datas = ();
my $title = $c->l('clm_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('clm_DESC_FILESYSTEM_SCAN_PERIOD'));
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$clm_datas{'FilesystemScan'} = ($db->get_prop('clamav', 'FilesystemScan')) || 'disabled';
$clm_datas{'Quarantine'} = ($db->get_prop('clamav', 'Quarantine')) || 'disabled';
$clm_datas{'clam_versions'} = get_clam_versions();
@@ -53,6 +54,7 @@ sub do_update {
sub change_settings {
my $c = shift;
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $status = $c->param('status');
my $FilesystemScan = ($c->param('FilesystemScan') || 'disabled');
my $Quarantine = ($c->param('Quarantine') || 'disabled');

View File

@@ -0,0 +1,359 @@
#
# Generated by SM2Gen version:0.9(20Jan2025) Chameleon version:4.5.4 On Python:3.12.3 at 2025-06-15 12:45:47
#
#
# Routines to be edited by the developer to provide content and validation for parameters
# and provison of the control data for table(s)
#
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB;
use esmith::NetworksDB::UTF8;
use esmith::HostsDB;
use esmith::DomainsDB::UTF8;
use DateTime;
use constant FALSE => 0;
use constant TRUE => 1;
#The most common ones - open DB when required.
my $cdb;
my $adb;
my $ndb;
my $hdb;
my $ddb;
#The most common ones - you might want to use these if you need to make sure that the DB is refreshed.
#$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
#$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
#$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
#$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
#$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
# Validation routines - parameters for each panel
sub validate_PARAMS {
my $c = shift;
my $dat_data = shift; #Data hash as parameter
# Validation for each field
my $ret = '';
if (! TRUE) #validate $c->param('time_mode')
{$ret .= 'Validation for time_mode failed';}
if (! TRUE) #validate $c->param('ntpserver')
{$ret .= 'Validation for ntpserver failed';}
if (! TRUE) #validate $c->param('year')
{$ret .= 'Validation for year failed';}
if (! TRUE) #validate $c->param('month')
{$ret .= 'Validation for month failed';}
if (! TRUE) #validate $c->param('day')
{$ret .= 'Validation for day failed';}
if (! TRUE) #validate $c->param('hour')
{$ret .= 'Validation for hour failed';}
if (! TRUE) #validate $c->param('minute')
{$ret .= 'Validation for minute failed';}
if (! TRUE) #validate $c->param('second')
{$ret .= 'Validation for second failed';}
if ($ret eq '') {$ret = 'ok';}
return $ret;
}
# Get singleton data for each panel
sub get_data_for_panel_PARAMS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
# --- Setup options ---
# Get today's date and time
my ($today_sec, $today_min, $today_hour, $today_mday, $today_mon, $today_year) = localtime;
$today_year += 1900;
$today_mon += 1;
my $today_mon = sprintf('%02d', $today_mon);
my $today_mday = sprintf('%02d', $today_mday);
my $now_hour = sprintf('%02d', $today_hour);
my $now_min = sprintf('%02d', $today_min);
my $now_sec = sprintf('%02d', $today_sec);
my $current_year = $today_year;
my $ntpserverurl = $cdb->get_prop('ntpd','NTPServer');
my $now = DateTime->now( time_zone => 'local' );
my %ret = (
# fields from Inputs
'time_mode'=>($ntpserverurl eq '' ? 'dat_manually_set' : 'dat_ntp_server'),
'ntpserver'=>"$ntpserverurl",
'year'=>"$today_year",
'month'=>"$today_mon",
'day'=>"$today_mday",,
'hour'=>"$now_hour",
'minute'=>"$now_min",
'second'=>"$now_sec",
'ntpstatus' => $cdb->get_prop('ntpd','status') || 'disabled',
# and the current time as a full format
'currentdatetime' => $now->strftime('%Y-%m-%dT%H:%M:%S')
);
return %ret;
}
# Get control data for table(s)
# Return hash with values from row in which link clicked on table
sub get_selected_PARAMS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = ();
#gather the values here
return %ret;
}
#after sucessful modify or create or whatever and submit then perfom (if the params validate)
sub perform_PARAMS {
my $c = shift;
my $dat_data = shift; #Data hash as parameter
my $ret = '';
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
my $db = $cdb; #maybe one of the others
my $dbkey = 'ntpd';
# To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g."
#$ntpserverurl = ( $c->param('time_mode') eq 'dat_manually_set' ? '' : $c->param('ntpserver'));
#if (!$db->set_prop($dbkey,'NTPServer',$ntpserverurl,type=>'service'))
#{$ret .= 'Perform/save failed for NTPServer';}
#if (! TRUE) #copy or perform with value: year e.g. $db->set_prop($dbkey,'year',$c->param('year'),type=>'service'))
#{$ret .= 'Perform/save failed for year';}
#if (! TRUE) #copy or perform with value: month e.g. $db->set_prop($dbkey,'month',$c->param('month'),type=>'service'))
#{$ret .= 'Perform/save failed for month';}
#if (! TRUE) #copy or perform with value: day e.g. $db->set_prop($dbkey,'day',$c->param('day'),type=>'service'))
#{$ret .= 'Perform/save failed for day';}
#if (! TRUE) #copy or perform with value: hour e.g. $db->set_prop($dbkey,'hour',$c->param('hour'),type=>'service'))
#{$ret .= 'Perform/save failed for hour';}
#if (! TRUE) #copy or perform with value: minute e.g. $db->set_prop($dbkey,'minute',$c->param('minute'),type=>'service'))
#{$ret .= 'Perform/save failed for minute';}
#if (! TRUE) #copy or perform with value: second e.g. $db->set_prop($dbkey,'second',$c->param('second'),type=>'service'))
#{$ret .= 'Perform/save failed for second';}
if ($c->param('time_mode') eq 'dat_manually_set'){
# Time and date set manually
$ret .= $c->disable_ntp();
$ret .= $c->validate_change_datetime()
} else {
# Time set by ntp server - set up parameters to it
$ret = $c->update_ntpserver($c->param('ntpserver'))
}
if ($ret eq '') {$ret = 'ok';}
return $ret;
}
sub create_link{
# WIP
my ($c,$route, $panel, $index) = @_;
my $link = "$route?trt=$panel&Selected=$index";
return $link;
}
sub getZone_list {
my $c = shift;
#--------------------------------------------------
# Get a sorted list of time zones
#--------------------------------------------------
$ENV{BASH_ENV} = '';
if (!open(ZONES, "cd /usr/share/zoneinfo; /usr/bin/find . -type f -or -type l | /bin/grep '^./[A-Z]' |")) {
warn($c->l('COULD_NOT_OPEN_TZ_FILE') . $! . '.');
return undef;
}
my $zone;
my @zones = ();
while (defined($zone = <ZONES>)) {
chop($zone);
$zone =~ s/^.\///;
push @zones, $zone;
} ## end while (defined($zone = <ZONES>...))
close ZONES;
my @zt = sort @zones;
return \@zt;
} ## end sub getZone_list
sub getTimezone {
#--------------------------------------------------
# Figure out time zone by looking first looking at
# the configuration database value of TimeZone.
# If that is not defined, try and get it from /etc/localtime.
# If that doesn't work, default to US/Eastern.
#--------------------------------------------------
my $localtime;
my $timezonedefault = "US/Eastern";
if (defined $cdb->get('TimeZone')) {
$timezonedefault = $cdb->get('TimeZone')->value;
} else {
if (defined($localtime = readlink '/etc/localtime')) {
my $pos = index $localtime, 'zoneinfo/';
if ($pos > -1) {
$timezonedefault = substr $localtime, ($pos + 9);
}
} ## end if (defined($localtime...))
} ## end else [ if (defined $cdb->get(...))]
return $timezonedefault;
} ## end sub getTimezone
sub validate_change_datetime {
my $c = shift;
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
#--------------------------------------------------
# Untaint parameters and check for validity
#--------------------------------------------------
my $timezone = $c->param('Timezone');
if ($timezone =~ /^([\w\-]+\/?[\w\-+]*)$/) {
$timezone = $1;
} else {
$timezone = "US/Eastern";
}
my $month = $c->param('month');
my $day = $c->param('day');
my $year = $c->param('year');
if (!is_valid_date($year, $month, $day)){
return $c->l('dat_Invalid_date')
}
my $hour = $c->param('hour');
if ($hour =~ /^(\d{1,2})$/) {
$hour = $1;
} else {
$hour = "12";
}
if (($hour < 1) || ($hour > 23)) {
return $c->l('dat_INVALID_HOUR') . " $hour. " . $c->l('dat_BETWEEN_0_AND_23');
}
my $minute = $c->param('minute');
if ($minute =~ /^(\d{1,2})$/) {
$minute = $1;
} else {
$minute = "0";
}
if (($minute < 0) || ($minute > 59)) {
return $c->l('datINVALID_MINUTE') . " $minute. " . $c->l('dat_BETWEEN_0_AND_59');
}
my $second = $c->param('second');
if ($second =~ /^(\d{1,2})$/) {
$second = $1;
} else {
$second = "0";
}
if (($second < 0) || ($second > 59)) {
return $c->l('dat_INVALID_SECOND') . " $second. " . $c->l('dat_BETWEEN_0_AND_59');
}
#--------------------------------------------------
# Store time zone in configuration database
#--------------------------------------------------
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('TimeZone');
unless ($rec) {
$rec = $cdb->new_record('TimeZone', undef);
}
$rec->set_value($timezone);
$cdb->get('UnsavedChanges')->set_value($old);
#--------------------------------------------------
# Signal event to change time zone, system time
# and hardware clock
#--------------------------------------------------
my $newdate = sprintf "%02d%02d%02d%02d%04d.%02d", $month, $day, $hour, $minute, $year, $second;
$c->app->log->info("Changing date manually to $newdate");
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "timezone-update", $newdate); #TEMP!!!
return '';
} ## end sub validate_change_datetime
sub is_valid_date {
my ($year, $month, $day) = @_;
# Check if all parts are defined and integers
return 0 unless defined $year && defined $month && defined $day;
return 0 unless $year =~ /^\d+$/ && $month =~ /^\d+$/ && $day =~ /^\d+$/;
# Try to construct a DateTime object
eval {
DateTime->new(year => $year, month => $month, day => $day);
1;
} or return 0;
return 1;
}
sub update_ntpserver {
my $c = shift;
my $ntpserver = shift;
my $msg = '';
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
#------------------------------------------------------------
# Looks good; go ahead and change the parameters.
#------------------------------------------------------------
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', 'enabled');
$rec->set_prop('NTPServer', $ntpserver);
} else {
$rec = $cdb->new_record('ntpd',
{ type => 'service', status => 'enabled', SyncToHWClockSupported => 'yes', NTPServer => $ntpserver });
}
$cdb->get('UnsavedChanges')->set_value($old);
$msg = ''; #$c->l('dat_SETTINGS_CHANGED');
if ($ntpserver =~ /^\s*$/) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
$msg = $c->l('dat_INVALID_NTP_SERVER') if ($rec->prop('SyncToHWClockSupported') || 'yes') ne 'yes';
} ## end if ($ntpserver =~ /^\s*$/)
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "timeserver-update");
return $msg;
} ## end sub update_ntpserver
sub disable_ntp {
# make sure that the parameters are set for disabled
my $old = $cdb->get('UnsavedChanges')->value;
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
} else {
$rec = $cdb->new_record('ntpd',
{ type => 'service', status => 'enabled', SyncToHWClockSupported => 'yes', NTPServer => '' });
}
$cdb->get('UnsavedChanges')->set_value($old);
return '';
} ## end sub disable_ntp
1;

View File

@@ -1,356 +1,333 @@
package SrvMngr::Controller::Datetime;
#
# Generated by SM2Gen version:0.9(20Jan2025) Chameleon version:4.5.4 On Python:3.12.3 at 2025-06-15 12:45:47
# Remember that each route must be unique (else they just overwrite each other).
# you cannot have get and post on the same name and url.
#
#----------------------------------------------------------------------
# heading : System
# description : Date and time
# navigation : 4000 400
# navigation : 4000 300
#
# ######name : datetimet, method : post, url : /datetimet, ctlact : datetime#testntp
#
# routes : end
#------------------------------
#
# Documentation: https://wiki.contribs.org/Datetime
#----------------------------------------------------------------------
#
# Scheme of things:
#
# TBA!!
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use constant FALSE => 0;
use constant TRUE => 1;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use Data::Dumper;
use esmith::util;
use SrvMngr qw( gen_locale_date_string );
our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
use esmith::util::network;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB;
use esmith::NetworksDB;
use esmith::HostsDB::UTF8;
use esmith::DomainsDB::UTF8;
my $cdb;
my $adb;
my $ndb;
my $hdb;
my $ddb;
my %dat_data;
require '/usr/share/smanager/lib/SrvMngr/Controller/Datetime-Custom.pm'; #The code that is to be added by the developer
sub main {
#
# Initial entry - route is "/<whatever>"
#
#set initial panel
#for initial panel:
#Specifiy panel to enter
#load up _data hash with DB fields
#load up stash with pointer(s) to control fields hash(= get-))
#and a pointer to the prefix_data hash
#render initial panel
my $c = shift;
$c->app->log->info( $c->log_req );
#The most common ones - you might want to delete some of these if they are not used.
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
%dat_data = ();
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
$dat_data{'trt'} = 'PARAMS';
#Load any DB entries into the <prefix>_data area so as they are preset in the form
# which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE
my $db = $cdb; #pickup local or global db or Default to config
$c->do_display($dat_data{'trt'});
}
# Post request with params - submit from the form
sub do_update {
#
# Return after submit pushed on panel (this is a post) - route is "/<whatever>u"
# parameters in the params hash.
#
#load up all params into prefix_data hash:
#By panel (series of if statements - only one executed):
#call validate-PANEL() - return ret = ok or error message
#if validation not ok:
#render back to current panel with error message in stash
#otherwise:
#By panel (series of if statements - only one executed):
#do whatever is required: call perform-PANEL() - return 'ok' or Error Message
#call signal-event for any global actions specified (check it exists - error and continue?)
#if action smeserver-<whatever>-update exists
#signal_event smeserver-<whatever>-update
#call signal-event for any specific actions for thids panel (check it exists first - error and continue)
#set success in stash
#if no "nextpanel" entry:
#set firstpanel
#else
#set nextpanel
#call render
my $c = shift;
$c->app->log->info($c->log_req);
my %dat_datas = ();
#$c->app->log->info($c->param('month'));
#The most common ones - you might want to delete some of these if they are not used.
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
$dat_datas{ntpstatus} = 'disabled';
my $rec = $cdb->get('ntpd');
if ($rec) {
$dat_datas{'ntpserver'} = $rec->prop('NTPServer') || '';
# Accessing all POST/GET parameters
#my $params = $c->req->params->to_hash;
if ($rec->prop('status') eq 'enabled') {
$dat_datas{ntpstatus} = 'enabled'
unless ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' and $dat_datas{ntpserver} =~ m#^\s*$#;
}
} ## end if ($rec)
( $dat_datas{weekday}, $dat_datas{monthname}, $dat_datas{month}, $dat_datas{day}, $dat_datas{year},
$dat_datas{hour}, $dat_datas{minute}, $dat_datas{second}, $dat_datas{ampm}
)
= split /\|/,
`/bin/date '+%A|%B|%-m|%-d|%Y|%-I|%M|%S|%p'`;
# Get number of POST parameters
#my $num_params = keys scaler %$params;
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $dat_data{$key} = $value;
#}
# get rid of trailing carriage return on last field
chop($dat_datas{ampm});
$dat_datas{'now_string'} = gen_locale_date_string;
$c->stash(title => $title, modul => $modul, dat_datas => \%dat_datas);
$c->render('datetime');
} ## end sub main
# the value of trt will tell you which panel has returned
my $trt = $c->param('trt') || 'PARAMS'; #hidden control on every form.
my $ret = 'ok';
sub do_update {
my $c = shift;
my %dat_datas = ();
#Validate the parameters in a custom sub one for each panel (although only one of these will be executed)
my $thispanel;
if ($trt eq 'PARAMS'){
#Validate form parameters for panel PARAMS
$ret = $c->validate_PARAMS(\%dat_data);
$thispanel = 'PARAMS';
}
if ($ret ne 'ok'){
$c->stash(error => $c->l($ret));
$c->do_display($thispanel);
} else {
#Do whatever is needed, including writing values to the DB
if ($trt eq 'PARAMS'){
#do whatever is required ...
$ret = $c->perform_PARAMS(\%dat_data);
if ($ret ne 'ok') {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
dat_data => \%dat_data
);
$c->render(template => "datetime");
return
} else {
if ($c->param('time_mode') eq 'dat_manually_set') {
$c->stash( success => $c->l('dat_UPDATING_CLOCK'));
} else {
$c->stash( success => $c->l('dat_SETTINGS_CHANGED'));
}
}
}
# and call any signal-events needed
#TBD
# Setup shared data and call panel
if ('none' eq 'none') {
$dat_data{'trt'} = 'PARAMS';
} else {
$dat_data{'trt'} = 'none';
}
$c->do_display($dat_data{'trt'});
}
}
sub do_display {
#
# Return after link clicked in table (this is a get) - route is "/<whatever>d"
# Expects ?trt=PANEL&selected="TableRowName" plus any other required
#
# OR it maybe a post from the main panel to add a new record
#
#load up all supplied params into prefix_data hash
#call get-selected-PANEL() - returns hash of all relevent parameters
#load up returned hash into prefix_data
#render - to called panel
my ($c,$trt) = @_;
$c->app->log->info($c->log_req);
#The most common ones - you might want to delete some of these if they are not used.
$cdb = esmith::ConfigDB::UTF8->open() || die("Couldn't open config db");
$adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
$ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
$hdb = esmith::HostsDB::UTF8->open() || die("Couldn't open Hosts db");
$ddb = esmith::DomainsDB::UTF8->open() || die("Couldn't open Domains db");
my $title = $c->l('dat_FORM_TITLE');
my $modul = $c->l('dat_INITIAL_DESC');
my $result;
my $success;
my $old_ntpstatus = $c->param('Old_ntpstatus');
$dat_datas{ntpstatus} = $c->param('Ntpstatus');
if ($dat_datas{ntpstatus} ne $old_ntpstatus) {
if ($dat_datas{ntpstatus} eq 'disabled') {
( $dat_datas{weekday}, $dat_datas{monthname}, $dat_datas{month},
$dat_datas{day}, $dat_datas{year}, $dat_datas{hour},
$dat_datas{minute}, $dat_datas{second}, $dat_datas{ampm}
)
= split /\|/,
`/bin/date '+%A|%B|%-m|%-d|%Y|%-I|%M|%S|%p'`;
# Accessing all parameters
#my $params = $c->req->params->to_hash;
# get rid of trailing carriage return on last field
chop($dat_datas{ampm});
} else {
$dat_datas{ntpserver} = ($cdb->get_prop('ntpd', 'NTPServer')) || '';
}
$dat_datas{now_string} = esmith::FormMagick->gen_locale_date_string();
$c->stash(title => $title, modul => $modul, dat_datas => \%dat_datas);
return $c->render('datetime');
} ## end if ($dat_datas{ntpstatus...})
# Get number of parameters
#my $num_params = keys %$params;
#Tag as Post or Get (ie. create new entry or edit existing one
my $is_new_record = ($c->req->method() eq 'POST');
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $dat_data{$key} = $value;
#}
if ($dat_datas{ntpstatus} eq 'enabled') {
# the value of trt will tell you which panel has returned
if (! $trt){
$trt = $c->param('trt') || 'PARAMS'; #Indicates where to go now
}
# Now add in the params from the selected row from the table
my %selectedrow;
if ($trt eq 'PARAMS'){
#Validate Get selected row (if applicable) PARAMS
%selectedrow = $c->get_selected_PARAMS($dat_data{'Selected'},$is_new_record);
}
#Copy in the selected row params to the prefix_data hash to pass to the panel
while (my ($key, $value) = each %selectedrow){
$dat_data{$key} = $value;
}
# Where to go now
$dat_data{'trt'} = $trt;
# Set up other shared data according to the panel to go to
if ($trt eq 'PARAMS'){
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_PARAMS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$dat_data{$key} = $value;
}
}
# and table control fields
# Data for panel
$c->stash(
title => $title,
modul => $modul,
dat_data => \%dat_data
);
$c->render(template => "datetime");
}
# update ntpserver
$dat_datas{ntpserver} = $c->param('Ntpserver') || '';
if ($dat_datas{ntpserver} eq "pool.ntp.org") {
$result .= $c->l('dat_INVALID_NTP_ADDR');
} elsif ($dat_datas{ntpserver} =~ /^([a-zA-Z0-9\.\-]+)$/) {
$dat_datas{ntpserver} = $1;
# } elsif ( $dat_datas{ntpserver} =~ /^\s*$/ ) {
# $dat_datas{ntpserver} = "";
} else {
$result .= $c->l('dat_INVALID_NTP_ADDR');
}
if (!$result) {
$success = update_ntpserver($c, $dat_datas{ntpserver});
}
} else {
# set Locale time & clean ntpserver
#my $servername = ($c->param('ServerName') || 'WS');
if (!$result) {
$result = validate_change_datetime($c);
if ($result eq 'OK') {
$success = $c->l('dat_UPDATING_CLOCK');
$result = '';
disable_ntp();
$success .= '<br>' . $c->l('dat_SERVER_DISABLED_DESC');
} ## end if ($result eq 'OK')
} ## end if (!$result)
} ## end else [ if ($dat_datas{ntpstatus...})]
if ($result) {
$c->stash(error => $result);
$c->stash(title => $title, modul => $modul, dat_datas => \%dat_datas);
return $c->render('datetime');
} ## end if ($result)
#$result = $c->l('dat_SUCCESS');
my $message = "'Datetime' update DONE";
$c->app->log->info($message);
$c->flash(success => $success);
$c->redirect_to('/datetime');
} ## end sub do_update
sub validate_change_datetime {
sub do_testntp {
my $c = shift;
my $server = $c->req->json->{ntpserver} // '';
#--------------------------------------------------
# Untaint parameters and check for validity
#--------------------------------------------------
my $timezone = $c->param('Timezone');
if ($timezone =~ /^([\w\-]+\/?[\w\-+]*)$/) {
$timezone = $1;
} else {
$timezone = "US/Eastern";
}
my $month = $c->param('Month');
if ($month =~ /^(\d{1,2})$/) {
$month = $1;
} else {
$month = "1";
# Strict validation: hostname or IPv4
unless ($server =~ /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*|\d{1,3}(?:\.\d{1,3}){3})$/) {
return $c->render(json => { success => 0, error => 'Invalid server name or IP' });
}
if (($month < 1) || ($month > 12)) {
return $c->l('dat_INVALID_MONTH') . " $month. " . $c->l('dat_MONTH_BETWEEN_1_AND_12');
}
my $day = $c->param('Day');
my $timeout = 5;
my @cmd = ('timeout', $timeout, 'ntpdate', '-q', $server);
if ($day =~ /^(\d{1,2})$/) {
$day = $1;
} else {
$day = "1";
# Run ntpdate and capture output
my $output = qx{@cmd 2>&1};
$c->app->log->info($output);
my $exit_code = $? >> 8;
# Parse for known errors
if ($exit_code == 124) {
return $c->render(json => { success => 0, error => "Timeout: NTP server did not respond within $timeout seconds" });
}
if ($output =~ /no server suitable for synchronization found/i) {
return $c->render(json => { success => 0, error => "No suitable NTP server found or server unreachable" });
}
if ($output =~ /Name or service not known|Temporary failure in name resolution/i) {
return $c->render(json => { success => 0, error => "DNS resolution failed for $server" });
}
if ($output =~ /ntpdig: no eligible servers/i) {
return $c->render(json => { success => 0, error => "Not a an NTP server" });
}
if ($output =~ /permission denied/i) {
return $c->render(json => { success => 0, error => "Permission denied running ntpdate" });
}
if ($exit_code != 0) {
return $c->render(json => { success => 0, error => "ntpdate failed (exit code $exit_code): $output" });
}
if (($day < 1) || ($day > 31)) {
return $c->l('dat_INVALID_DAY') . " $day. " . $c->l('dat_BETWEEN_1_AND_31');
}
my $year = $c->param('Year');
# Extract date and time down to seconds from adjust line
my ($datetime) = $output =~ /^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/m;
if ($year =~ /^(\d{4})$/) {
$year = $1;
} else {
$year = "2000";
}
if ($datetime) {
return $c->render(json => { success => 1, time => $datetime });
} else {
return $c->render(json => { success => 0, error => "Could not parse date/time from NTP server response." });}
}
if (($year < 1900) || ($year > 2200)) {
return $c->l('dat_INVALID_YEAR') . " $year. " . $c->l('dat_FOUR_DIGIT_YEAR');
}
my $hour = $c->param('Hour');
if ($hour =~ /^(\d{1,2})$/) {
$hour = $1;
} else {
$hour = "12";
}
if (($hour < 1) || ($hour > 12)) {
return $c->l('dat_INVALID_HOUR') . " $hour. " . $c->l('dat_BETWEEN_1_AND_12');
}
my $minute = $c->param('Minute');
if ($minute =~ /^(\d{1,2})$/) {
$minute = $1;
} else {
$minute = "0";
}
if (($minute < 0) || ($minute > 59)) {
return $c->l('datINVALID_MINUTE') . " $minute. " . $c->l('dat_BETWEEN_0_AND_59');
}
my $second = $c->param('Second');
if ($second =~ /^(\d{1,2})$/) {
$second = $1;
} else {
$second = "0";
}
if (($second < 0) || ($second > 59)) {
return $c->l('dat_INVALID_SECOND') . " $second. " . $c->l('dat_BETWEEN_0_AND_59');
}
my $ampm = $c->param('Ampm');
if ($ampm =~ /^(AM|PM)$/) {
$ampm = $1;
} else {
$ampm = "AM";
}
# convert to 24 hour time
$hour = $hour % 12;
if ($ampm eq "PM") {
$hour = $hour + 12;
}
#--------------------------------------------------
# Store time zone in configuration database
#--------------------------------------------------
my $conf = esmith::ConfigDB->open();
my $old = $conf->get('UnsavedChanges')->value;
my $rec = $conf->get('TimeZone');
unless ($rec) {
$rec = $conf->new_record('TimeZone', undef);
}
$rec->set_value($timezone);
$conf->get('UnsavedChanges')->set_value($old);
#--------------------------------------------------
# Signal event to change time zone, system time
# and hardware clock
#--------------------------------------------------
my $newdate = sprintf "%02d%02d%02d%02d%04d.%02d", $month, $day, $hour, $minute, $year, $second;
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "timezone-update", $newdate);
return 'OK';
} ## end sub validate_change_datetime
sub update_ntpserver {
my $c = shift;
my $ntpserver = shift;
my $msg;
#------------------------------------------------------------
# Looks good; go ahead and change the parameters.
#------------------------------------------------------------
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', 'enabled');
$rec->set_prop('NTPServer', $ntpserver);
} else {
$rec = $cdb->new_record('ntpd',
{ type => 'service', status => 'enabled', SyncToHWClockSupported => 'yes', NTPServer => $ntpserver });
}
$cdb->get('UnsavedChanges')->set_value($old);
$msg = $c->l('dat_SETTINGS_CHANGED');
if ($ntpserver =~ /^\s*$/) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
$msg = $c->l('dat_INVALID_NTP_SERVER') if ($rec->prop('SyncToHWClockSupported') || 'yes') ne 'yes';
} ## end if ($ntpserver =~ /^\s*$/)
esmith::util::backgroundCommand(2, "/sbin/e-smith/signal-event", "timeserver-update");
return $msg;
} ## end sub update_ntpserver
sub disable_ntp {
# make sure that the parameters are set for disabled
my $old = $cdb->get('UnsavedChanges')->value;
my $rec = $cdb->get('ntpd');
if ($rec) {
$rec->set_prop('status', ($rec->prop('SyncToHWClockSupported') || 'yes') eq 'yes' ? 'enabled' : 'disabled');
$rec->set_prop('NTPServer', '');
} else {
$rec = $cdb->new_record('ntpd',
{ type => 'service', status => 'enabled', SyncToHWClockSupported => 'yes', NTPServer => '' });
}
$cdb->get('UnsavedChanges')->set_value($old);
} ## end sub disable_ntp
sub getTimezone {
#--------------------------------------------------
# Figure out time zone by looking first looking at
# the configuration database value of TimeZone.
# If that is not defined, try and get it from /etc/localtime.
# If that doesn't work, default to US/Eastern.
#--------------------------------------------------
my $localtime;
my $timezonedefault = "US/Eastern";
if (defined $cdb->get('TimeZone')) {
$timezonedefault = $cdb->get('TimeZone')->value;
} else {
if (defined($localtime = readlink '/etc/localtime')) {
my $pos = index $localtime, 'zoneinfo/';
if ($pos > -1) {
$timezonedefault = substr $localtime, ($pos + 9);
}
} ## end if (defined($localtime...))
} ## end else [ if (defined $cdb->get(...))]
return $timezonedefault;
} ## end sub getTimezone
sub getZone_list {
my $c = shift;
#--------------------------------------------------
# Get a sorted list of time zones
#--------------------------------------------------
$ENV{BASH_ENV} = '';
if (!open(ZONES, "cd /usr/share/zoneinfo; /usr/bin/find . -type f -or -type l | /bin/grep '^./[A-Z]' |")) {
warn($c->l('COULD_NOT_OPEN_TZ_FILE') . $! . '.');
return undef;
}
my $zone;
my @zones = ();
while (defined($zone = <ZONES>)) {
chop($zone);
$zone =~ s/^.\///;
push @zones, $zone;
} ## end while (defined($zone = <ZONES>...))
close ZONES;
my @zt = sort @zones;
return \@zt;
} ## end sub getZone_list
sub getMonth_list {
my $c = shift;
return [
[ $c->l('dat_JANUARY') => '1' ],
[ $c->l('dat_FEBRUARY') => '2' ],
[ $c->l('dat_MARCH') => '3' ],
[ $c->l('dat_APRIL') => '4' ],
[ $c->l('dat_MAY') => '5' ],
[ $c->l('dat_JUNE') => '6' ],
[ $c->l('dat_JULY') => '7' ],
[ $c->l('dat_AUGUST') => '8' ],
[ $c->l('dat_SEPTEMBER') => '9' ],
[ $c->l('dat_OCTOBER') => '10' ],
[ $c->l('dat_NOVEMBER') => '11' ],
[ $c->l('dat_DECEMBER') => '12' ]
];
} ## end sub getMonth_list
1;
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Directory;
#----------------------------------------------------------------------
# heading : User management
# description : Directory
# navigation : 2000 300
# navigation : 2000 400
#
# routes : end
#----------------------------------------------------------------------
@@ -12,13 +12,16 @@ use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use SrvMngr qw(theme_list init_session);
our $db = esmith::ConfigDB->open() || die "Couldn't open config db";
our $db;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my %dir_datas = ();
my $title = $c->l('dir_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('dir_DESCRIPTION'));
@@ -52,7 +55,7 @@ sub do_update {
$db->get('ldap')->set_prop('defaultPhoneNumber', $phonenumber);
if ($existing eq 'update') {
my $ac = esmith::AccountsDB->open() || die "Couldn't open accounts db";
my $ac = esmith::AccountsDB::UTF8->open() || die "Couldn't open accounts db";
my @users = $ac->users();
foreach my $user (@users) {

View File

@@ -13,16 +13,10 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::DomainsDB::UTF8;
use esmith::AccountsDB::UTF8;
#use Data::Dumper;
#use esmith::FormMagick::Panel::domains;
use esmith::DomainsDB;
use esmith::AccountsDB;
#use URI::Escape;
my ($ddb,$cdb,$adb);
#our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
our ($ddb,$cdb,$adb);
our $REGEXP_DOMAIN = qq([a-zA-Z0-9\-\.]+);
sub main {
@@ -30,9 +24,9 @@ sub main {
$c->app->log->info($c->log_req);
my %dom_datas = ();
my $title = $c->l('dom_FORM_TITLE');
$ddb = esmith::DomainsDB->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$dom_datas{trt} = 'LST';
my @domains;
@@ -57,9 +51,9 @@ sub do_display {
my $rt = $c->current_route;
my $trt = $c->param('trt');
my $domain = $c->param('Domain') || '';
$ddb = esmith::DomainsDB->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
#$trt = 'DEL' if ( $rt eq 'domaindel1' );
#$trt = 'UPD' if ( $rt eq 'domainupd1' );
@@ -127,9 +121,9 @@ sub do_update {
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = $c->param('trt');
$ddb = esmith::DomainsDB->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my %dom_datas = ();
my ($res, $result) = '';
@@ -246,6 +240,7 @@ sub create_modify_domain {
. ' Ctl'
);
} ## end unless ($domain)
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
my $rec = $ddb->get($domain);
if ($rec and $action eq 'create') {
@@ -375,6 +370,7 @@ sub nameserver_options_list {
sub get_nameserver_value {
my $c = shift;
$ddb = esmith::DomainsDB::UTF8->open || die "Couldn't open domains db";
my $domain = $c->param('Domain') || undef;
return ($ddb->get_prop($domain, 'Nameservers') || 'internet');
} ## end sub get_nameserver_value

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Emailsettings;
#----------------------------------------------------------------------
# heading : System
# description : E-mail
# navigation : 4000 500
# navigation : 4000 400
#
#
# routes : end
@@ -16,16 +16,18 @@ use constant TRUE => 1;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number_or_blank);
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use esmith::util;
use File::Basename;
our $pattern_db = esmith::ConfigDB->open("mailpatterns");
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
our $pattern_db;
our $cdb;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$pattern_db = esmith::ConfigDB::UTF8->open("mailpatterns");
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %mai_datas = ();
my $title = $c->l('mai_FORM_TITLE');
$mai_datas{'trt'} = 'LIST';
@@ -42,7 +44,7 @@ sub do_display {
my $title = $c->l('mai_FORM_TITLE');
my ($notif, $dest) = '';
$mai_datas{'trt'} = $trt;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
if ($trt eq 'ACC') {
$dest = 'emailaccess';
@@ -94,7 +96,7 @@ sub do_update {
my $trt = $c->param('trt');
my %mai_datas = ();
$mai_datas{trt} = $trt;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $title = $c->l('mai_FORM_TITLE');
my ($dest, $res, $result) = '';
@@ -231,7 +233,7 @@ sub get_patterns_status {
sub adjust_patterns {
my $c = shift;
my @selected = @{ $c->every_param('BlockExecutableContent') };
$pattern_db = esmith::ConfigDB::UTF8->open("mailpatterns");
foreach my $pattern ($pattern_db->get_all_by_prop(type => "pattern")) {
my $status
= (grep $pattern->key eq $_, @selected)
@@ -284,7 +286,7 @@ sub get_current_imap_access {
sub get_current_smtp_ssl_auth {
my ($c, $localise, $soru, $debug) = @_;
die "Error: \$soru must be either 's' or 'u':$soru.\n" unless $soru eq 's' || $soru eq 'u';
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
# Initialize variables with default values
my $smtpStatus = 'none';
@@ -485,7 +487,7 @@ sub get_retrieval_opt {
sub get_emailunknownuser_options {
my $c = shift;
my $accounts = esmith::AccountsDB->open_ro();
my $accounts = esmith::AccountsDB::UTF8->open_ro();
my %existingAccounts = (
'admin' => $c->l("mai_FORWARD_TO_ADMIN"),
'returntosender' => $c->l("mai_RETURN_TO_SENDER")
@@ -503,7 +505,7 @@ sub get_emailunknownuser_options {
sub get_emailunknownuser_opt {
my $c = shift;
my $accounts = esmith::AccountsDB->open_ro();
my $accounts = esmith::AccountsDB::UTF8->open_ro();
my @existingAccounts
= ([ $c->l("mai_FORWARD_TO_ADMIN") => 'admin' ], [ $c->l("mai_RETURN_TO_SENDER") => 'returntosender' ]);
@@ -580,14 +582,13 @@ sub display_multidrop {
sub change_settings_reception {
my $c = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDBi::UTF8->open || die "Couldn't open config db";
my $FetchmailMethod = ($c->param('FetchmailMethod') || 'standard');
my $FetchmailFreqOffice = ($c->param('FreqOffice') || 'every15min');
my $FetchmailFreqOutside = ($c->param('FreqOutside') || 'everyhour');
my $FetchmailFreqWeekend = ($c->param('FreqWeekend') || 'everyhour');
my $SpecifyHeader = ($c->param('SpecifyHeader') || 'off');
my $fetchmail
= $cdb->get('fetchmail') || $cdb->new_record("fetchmail", { type => "service", status => "disabled" });
my $fetchmail = $cdb->get('fetchmail') || $cdb->new_record("fetchmail", { type => "service", status => "disabled" });
if ($FetchmailMethod eq 'standard') {
$fetchmail->set_prop('status', 'disabled');
@@ -662,7 +663,7 @@ sub change_settings_reception {
sub change_settings_delivery {
my ($c) = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $EmailUnknownUser = ($c->param('EmailUnknownUser') || 'returntosender');
$cdb->set_value('SMTPSmartHost', $c->param('SMTPSmartHost'));
$cdb->set_value('DelegateMailServer', $c->param('DelegateMailServer'));
@@ -683,7 +684,7 @@ sub change_settings_delivery {
sub change_settings_access {
my $c = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $pop3Access = ($c->param('POPAccess') || 'private');
if ($pop3Access eq 'disabled') {
@@ -757,7 +758,7 @@ sub change_settings_access {
sub change_settings_filtering {
my $c = shift;
$cdb = esmith::ConfigDB->open || die "Couldn't open config db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $virus_status = ($c->param('VirusStatus') || 'disabled');
$cdb->set_prop("qpsmtpd", 'VirusScan', $virus_status);

View File

@@ -14,21 +14,18 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::AccountsDB::UTF8;
use esmith::ConfigDB::UTF8;
#use Data::Dumper;
#use esmith::FormMagick::Panel::groups;
use esmith::AccountsDB;
#our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
my ($cdb,$adb);
our ($cdb,$adb);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %grp_datas = ();
my $title = $c->l('grp_FORM_TITLE');
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$grp_datas{trt} = 'LST';
my @groups;
@@ -47,8 +44,8 @@ sub do_display {
my $group = $c->param('group');
my %grp_datas = ();
my $title = $c->l('grp_FORM_TITLE');
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$grp_datas{'trt'} = $trt;
if ($trt eq 'ADD') {
@@ -104,8 +101,8 @@ sub do_update {
my $title = $c->l('grp_FORM_TITLE');
my ($res, $result) = '';
my %grp_datas = ();
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$grp_datas{'trt'} = $trt;
$grp_datas{'group'} = $groupName;
my @members = ();

View File

@@ -14,22 +14,14 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use Data::Dumper;
#use esmith::FormMagick::Panel::hostentries;
use esmith::DomainsDB;
use esmith::AccountsDB;
use esmith::HostsDB;
use esmith::NetworksDB;
use HTML::Entities;
use Net::IPv4Addr qw(ipv4_in_network);
use esmith::DomainsDB::UTF8;
use esmith::ConfigDB::UTF8;
use esmith::HostsDB::UTF8;
use esmith::NetworksDB::UTF8;
#use URI::Escape;
#our $ddb = esmith::DomainsDB->open || die "Couldn't open hostentries db";
#our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
#our $hdb = esmith::HostsDB->open || die "Couldn't open hosts db";
#our $ndb = esmith::NetworksDB->open || die "Couldn't open networks db";
my ($ddb,$cdb,$hdb,$ndb);
our ($ddb,$cdb,$hdb,$ndb);
sub main {
my $c = shift;
@@ -37,10 +29,9 @@ sub main {
my %hos_datas = ();
my $title = $c->l('hos_FORM_TITLE');
my $notif = '';
#my $ddb = esmith::DomainsDB->open || die "Couldn't open hostentries db";
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB->open || die "Couldn't open networks db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB::UTF8->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
$hos_datas{trt} = 'LIST';
my %dom_hosts = ();
@@ -73,9 +64,9 @@ sub do_display {
$trt = 'LST' if ($trt ne 'DEL' && $trt ne 'UPD' && $trt ne 'ADD');
my %hos_datas = ();
my $title = $c->l('hos_FORM_TITLE');
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB->open || die "Couldn't open networks db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB::UTF8->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
my $notif = '';
$hos_datas{'trt'} = $trt;
@@ -120,9 +111,9 @@ sub do_update {
my $trt = ($c->param('trt') || 'LIST');
my %hos_datas = ();
my $title = $c->l('hos_FORM_TITLE');
$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB->open || die "Couldn't open networks db";
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open configuration db";
$hdb = esmith::HostsDB::UTF8->open || die "Couldn't open hosts db";
$ndb = esmith::NetworksDB::UTF8->open || die "Couldn't open networks db";
my $notif = '';
my $result = '';
$hos_datas{'name'} = lc $c->param('Name');
@@ -379,10 +370,10 @@ sub delete_hostentry {
} ## end sub delete_hostentry
sub domains_list {
my $d = esmith::DomainsDB->open_ro() or die "Couldn't open DomainsDB";
$ddb = esmith::DomainsDB::UTF8->open_ro() or die "Couldn't open DomainsDB";
my @domains;
for ($d->domains) {
for ($ddb->domains) {
my $ns = $_->prop("Nameservers") || 'localhost';
push @domains, $_->key if ($ns eq 'localhost');
}
@@ -516,7 +507,7 @@ sub must_be_local {
my $localip = shift;
# Make sure that the IP is indeed local.
#my $ndb = esmith::NetworksDB->open_ro;
#$ndb = esmith::NetworksDB::UTF8->open_ro;
my @local_list = $ndb->local_access_spec;
foreach my $spec (@local_list) {

View File

@@ -2,7 +2,7 @@ package SrvMngr::Controller::Ibays;
#----------------------------------------------------------------------
# heading : Network
# description : Shared areas (was ibays)
# description : Ibays
# navigation : 6000 100
#
#
@@ -13,13 +13,11 @@ use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw( theme_list init_session is_normal_password );
use esmith::AccountsDB;
use esmith::ConfigDB;
use esmith::DomainsDB;
use SrvMngr qw( theme_list init_session validate_password );
use esmith::AccountsDB::UTF8;
use esmith::ConfigDB::UTF8;
use esmith::DomainsDB::UTF8;
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
#our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
my ($adb,$cdb);
sub main {
@@ -27,9 +25,9 @@ sub main {
$c->app->log->info($c->log_req);
my %iba_datas = ();
my $title = $c->l('iba_FORM_TITLE');
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
$iba_datas{'trt'} = 'LIST';
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$iba_datas{'trt'} = 'LIST';
my @ibays;
if ($adb) {
@@ -44,8 +42,8 @@ sub do_display {
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $ibay = $c->param('ibay') || '';
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
#$trt = 'DEL' if ( $ibay );
#$trt = 'ADD' if ( $rt eq 'ibayadd' );
@@ -99,7 +97,7 @@ sub do_display {
if ($trt eq 'LIST') {
my @ibays;
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
if ($adb) {
@ibays = $adb->ibays();
@@ -120,8 +118,8 @@ sub do_update {
$iba_datas{'trt'} = $trt;
my $result = '';
my $res;
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
if ($trt eq 'ADD') {
my $name = ($c->param('ibay') || '');
@@ -306,7 +304,7 @@ sub print_vhost_message {
my $c = shift;
my $name = $c->param('ibay');
my $result = '';
my $domaindb = esmith::DomainsDB->open();
my $domaindb = esmith::DomainsDB::UTF8->open();
my @domains = $domaindb->get_all_by_prop(Content => $name);
my $vhostListItems = join "\n", (map ($_->key . " " . $_->prop('Description'), @domains));
@@ -328,7 +326,7 @@ sub remove_ibay {
if (my $acct = $adb->get($name)) {
if ($acct->prop('type') eq 'ibay') {
$acct->set_prop('type', 'ibay-deleted');
my $domains_db = esmith::DomainsDB->open();
my $domains_db = esmith::DomainsDB::UTF8->open();
my @domains = $domains_db->get_all_by_prop(Content => $name);
foreach my $d (@domains) {
@@ -385,31 +383,6 @@ sub check_password {
return validate_password($c, $strength, $password);
} ## end sub check_password
sub validate_password {
my ($c, $strength, $pass) = @_;
use Crypt::Cracklib;
my $reason;
if ($strength eq "none") {
return $c->l("Passwords must be at least 7 characters long") unless (length($pass) > 6);
return "OK";
}
$reason = is_normal_password($c, $pass, undef);
return $reason unless ($reason eq "OK");
return "OK" unless ($strength eq "strong");
if (-f '/usr/lib64/cracklib_dict.pwd') {
$reason = fascist_check($pass, '/usr/lib64/cracklib_dict');
} else {
$reason = fascist_check($pass, '/usr/lib/cracklib_dict');
}
$reason ||= "Software error: password check failed";
return "OK" if ($reason eq "ok");
return
$c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because") . " "
. $c->($reason) . ".";
} ## end sub validate_password
=head2 group_list()

View File

@@ -1,566 +0,0 @@
#
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-11-16 10:30:16
#
#
# Routines to be edited by the developer to provide content and validation for parameters
# and provison of the control data for table(s)
#
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB;
use esmith::HostsDB;
use esmith::AccountsDB;
use esmith::NetworksDB;
use esmith::DomainsDB;
use constant FALSE => 0;
use constant TRUE => 1;
#The most common ones
our $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
our $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
our $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
our $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
our $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
# Validation routines - parameters for each panel
sub validate_LIST {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (!TRUE) #validate $c->param('InternalIP')
{
$ret .= 'Validation for InternalIP failed';
}
if (!TRUE) #validate $c->param('ExternalIP')
{
$ret .= 'Validation for ExternalIP failed';
}
if (!TRUE) #validate $c->param('InternetIP')
{
$ret .= 'Validation for InternetIP failed';
}
if (!TRUE) #validate $c->param('Issuer')
{
$ret .= 'Validation for Issuer failed';
}
if (!TRUE) #validate $c->param('Expiry')
{
$ret .= 'Validation for Expiry failed';
}
if (!TRUE) #validate $c->param('NotBefore')
{
$ret .= 'Validation for NotBefore failed';
}
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub validate_LIST
sub validate_PARAMS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (!TRUE) #validate $c->param('status')
{
$ret .= 'Validation for status failed';
}
if (!TRUE) #validate $c->param('hookScript')
{
$ret .= 'Validation for hookScript failed';
}
if (!TRUE) #validate $c->param('hostOverride')
{
$ret .= 'Validation for hostOverride failed';
}
if (!TRUE) #validate $c->param('ACCEPT_TERMS')
{
$ret .= 'Validation for ACCEPT_TERMS failed';
}
if (!TRUE) #validate $c->param('API')
{
$ret .= 'Validation for API failed';
}
if (!TRUE) #validate $c->param('keysize')
{
$ret .= 'Validation for keysize failed';
}
if (!TRUE) #validate $c->param('configure')
{
$ret .= 'Validation for configure failed';
}
if (!TRUE) #validate $c->param('Email')
{
$ret .= 'Validation for Email failed';
}
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub validate_PARAMS
sub validate_CHECKALLDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (!TRUE) #validate $c->param('AllDomainsCheck')
{
$ret .= 'Validation for AllDomainsCheck failed';
}
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub validate_CHECKALLDOMAINS
sub validate_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (!TRUE) #validate $c->param('EnabledDomainsCheck')
{
$ret .= 'Validation for EnabledDomainsCheck failed';
}
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub validate_CHECKALLENABLEDDOMAINS
sub validate_CHECKONEDOMAIN {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
# Validation for each field
my $ret = "";
if (!TRUE) #validate $c->param('OneDomainToCheck')
{
$ret .= 'Validation for OneDomainToCheck failed';
}
if (!TRUE) #validate $c->param('OneDomainsCheck')
{
$ret .= 'Validation for OneDomainsCheck failed';
}
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub validate_CHECKONEDOMAIN
# Get singleton data for each panel
sub get_data_for_panel_LIST {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
# my ($reply, $err, $server_cert) = Net::SSLeay::sslcat('localhost', 443, '/');
# my $issuer = Net::SSLeay::X509_NAME_oneline(Net::SSLeay::X509_get_issuer_name($server_cert));
# my $before = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notBefore($server_cert));
# my $expiry = Net::SSLeay::P_ASN1_TIME_get_isotime(Net::SSLeay::X509_get_notAfter($server_cert));
my %ret = (
'Data1' => 'Data for LIST', #Example
# fields from Inputs in LIST $fields['LIST']
'InternalIP' => $cdb->get_prop('InternalInterface', 'IPAddress'),
'ExternalIP' => $cdb->get_prop('ExternalInterface', 'IPAddress'),
'InternetIP' => $c->get_my_ip(),
'Issuer' => '$issuer',
'Expiry' => '$expiry',
'NotBefore' => '$before',
);
return %ret;
} ## end sub get_data_for_panel_LIST
sub get_data_for_panel_PARAMS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1' => 'Data for PARAMS', #Example
# fields from Inputs in PARAMS $fields['PARAMS']
'status' => $cdb->get_prop('letsencrypt', 'status', 'disabled'),
'hookScript' => $cdb->get_prop('letsencrypt', 'hookScript', 'disabled'),
'hostOverride' => $cdb->get_prop('letsencrypt', 'hostOverride', 'disabled'),
'ACCEPT_TERMS' => $cdb->get_prop('letsencrypt', 'ACCEPT_TERMS', ''),
'API' => $cdb->get_prop('letsencrypt', 'API', '2'),
'keysize' => $cdb->get_prop('letsencrypt', 'keysize', '4096'),
'configure' => $cdb->get_prop('letsencrypt', 'configure', 'none'),
'email' => $cdb->get_prop('letsencrypt', 'email')
);
return %ret;
} ## end sub get_data_for_panel_PARAMS
sub get_data_for_panel_CHECKALLDOMAINS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1' => 'Data for CHECKALLDOMAINS', #Example
# fields from Inputs in CHECKALLDOMAINS $fields['CHECKALLDOMAINS']
'AllDomainsCheck' => $c->update_all_domains(),
);
return %ret;
} ## end sub get_data_for_panel_CHECKALLDOMAINS
sub get_data_for_panel_CHECKALLENABLEDDOMAINS {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1' => 'Data for CHECKALLENABLEDDOMAINS', #Example
# fields from Inputs in CHECKALLENABLEDDOMAINS $fields['CHECKALLENABLEDDOMAINS']
'EnabledDomainsCheck' => $c->update_enabled_domains(),
);
return %ret;
} ## end sub get_data_for_panel_CHECKALLENABLEDDOMAINS
sub get_data_for_panel_CHECKONEDOMAIN {
# Return a hash with the fields required which will be loaded into the shared data
my $c = shift;
my %ret = (
'Data1' => 'Data for CHECKONEDOMAIN', #Example
# fields from Inputs in CHECKONEDOMAIN $fields['CHECKONEDOMAIN']
'OneDomainToCheck' => $c->param("CHECKONEDOMAIN"),
'OneDomainsCheck' => $c->update_one_domain($c->param("CHECKONEDOMAIN"))
);
return %ret;
} ## end sub get_data_for_panel_CHECKONEDOMAIN
# Get control data for table(s)
# Define a constant hash for field name mapping
use constant DomainList_FIELD_MAPPING => (
'Table1-Domain name / HOSTNAME' => 'Domain',
'Table1-Brief description' => 'Description',
'Table1-Content' => 'Content',
'Table1-LABEL_NAMESERVERS' => 'Nameservers',
'Table1-LABEL_POINT' => 'Source-for-Table1-LABEL_POINT',
'Table1-LABEL_LECERT' => 'letsencryptSSLcert',
'Table1-IS_IN_CERT' => 'isincert',
'Table1-CHECK' => 'Check'
#'target_field2' => 'source_field2',
# Add more mappings as needed
);
use constant TEST_DOMAIN_LIST => (
{ "domain" => "Domain1", "fred" => "fred1", "description" => "Description1" },
{ "domain" => "Domain2", "fred" => "fred2", "description" => "Description2" },
{ "domain" => "Domain3", "fred" => "fred3", "description" => "Description3" },
# Add more test entries as needed
);
sub actual_DomainList {
my $c = shift;
# Actual code for extracting DomainList
my @list = ();
# my @rv = Net::SSLeay::X509_get_subjectAltNames($server_cert);
# foreach my $element (@rv) {
# next if $element =~ /^\d+$/; ;
# #print $element . "\n";
# push @list, $element;
# }
my @data = ();
my $check = $c->l('Check Domain');
for ($ddb->domains) {
my $ns = $_->prop('Nameservers') || 'internet';
my $le = $_->prop('letsencryptSSLcert') || 'disabled'; #letsencrypt configure all
my $dname = $_->key;
my $isincert = "N";
my $link = $c->create_link("letsencryptd", "CHECKONEDOMAIN", "");
my $checklink = "<a href='" . $link . "&CHECKONEDOMAIN=" . $_->key . "'>" . $check . "</a>";
#my $checklink = "<a href=''>check</a>";
$isincert = "Y" if ($dname ~~ @list);
# domain
push @data,
{
Domain => $_->key,
$_->props,
letsencryptSSLcert => $le,
isincert => $isincert,
Check => $checklink,
Nameservers => $ns,
};
#and hosts
for my $h ($hdb->get_hosts_by_domain($dname)) {
next if $ddb->get($h->key);
next unless ($h->prop('HostType') eq "Self" || $h->prop('HostType') eq "Local");
$le = $h->prop('letsencryptSSLcert') || 'disabled'; #letsencrypt configure all
$isincert = "N";
$isincert = "Y" if ($h->key ~~ @list);
push @data, {
Domain => "--> " . $h->key,
$h->props,
Description => $h->prop('ExternalIP') || $h->prop('InternalIP') || "",
Content => $h->prop('HostType'),
isincert => $isincert,
Check => "", #$checklink
Nameservers => $c->l($ns),
};
} ## end for my $h ($hdb->get_hosts_by_domain...)
} ## end for ($ddb->domains)
return @data;
} ## end sub actual_DomainList
sub get_DomainList {
# Return an array of hashes of the contents for each row and column for DomainList
my $c = shift;
my @source_records
= $c->actual_DomainList(); #TEST_DOMAIN_LIST #Replace by code or call to produce contents of table;
my @transformed_records;
my %Field_Mapping = DomainList_FIELD_MAPPING;
# Iterate over each record in the source array
for my $source_record (@source_records) {
my %transformed_record;
# Iterate over each key-value pair in the $Field_Mapping constant
while (my ($target, $source) = each %Field_Mapping) {
# Check if the source field exists in the source record
if (exists $source_record->{$source}) {
# Assign the source field value to the target field in the transformed record
$transformed_record{$target} = $source_record->{$source};
}
} ## end while (my ($target, $source...))
# Add transformed record to the array if it's not empty
push @transformed_records, \%transformed_record if %transformed_record;
} ## end for my $source_record (...)
return \@transformed_records;
} ## end sub get_DomainList
# Return hash with values from row in which link clicked on table
sub get_selected_LIST {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return %ret;
} ## end sub get_selected_LIST
sub get_selected_PARAMS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return %ret;
} ## end sub get_selected_PARAMS
sub get_selected_CHECKALLDOMAINS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return %ret;
} ## end sub get_selected_CHECKALLDOMAINS
sub get_selected_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return %ret;
} ## end sub get_selected_CHECKALLENABLEDDOMAINS
sub get_selected_CHECKONEDOMAIN {
my $c = shift;
my $selected = shift; #Parameter is name of selected row.
my $is_new_record = shift; #Indicates new record required (defaults)
my %ret = {};
return %ret;
} ## end sub get_selected_CHECKONEDOMAIN
#after sucessful modify or create or whatever and submit then perfom (if the params validate)
sub perform_LIST {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (!TRUE
) #copy or perform with value: InternalIP e.g. $db->set_prop($dbkey,'InternalIP',$c->param('InternalIP'),type=>'service'))
{
$ret .= 'Perform/save failed for InternalIP';
} ## end if (!TRUE)
if (!TRUE
) #copy or perform with value: ExternalIP e.g. $db->set_prop($dbkey,'ExternalIP',$c->param('ExternalIP'),type=>'service'))
{
$ret .= 'Perform/save failed for ExternalIP';
} ## end if (!TRUE)
if (!TRUE
) #copy or perform with value: InternetIP e.g. $db->set_prop($dbkey,'InternetIP',$c->param('InternetIP'),type=>'service'))
{
$ret .= 'Perform/save failed for InternetIP';
} ## end if (!TRUE)
if (!TRUE
) #copy or perform with value: Issuer e.g. $db->set_prop($dbkey,'Issuer',$c->param('Issuer'),type=>'service'))
{
$ret .= 'Perform/save failed for Issuer';
} ## end if (!TRUE)
if (!TRUE
) #copy or perform with value: Expiry e.g. $db->set_prop($dbkey,'Expiry',$c->param('Expiry'),type=>'service'))
{
$ret .= 'Perform/save failed for Expiry';
} ## end if (!TRUE)
if (!TRUE
) #copy or perform with value: NotBefore e.g. $db->set_prop($dbkey,'NotBefore',$c->param('NotBefore'),type=>'service'))
{
$ret .= 'Perform/save failed for NotBefore';
} ## end if (!TRUE)
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub perform_LIST
sub perform_PARAMS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'letsencrypt';
# To make it write to DB as comment, delete this (regex) string in each if statement "TRUE\) \#copy or perform with value: .* e.g."
if (!$db->set_prop($dbkey, 'status', $c->param('status'), type => 'service')) {
$ret .= 'Perform/save failed for status';
}
if (!$db->set_prop($dbkey, 'hookScript', $c->param('hookScript'), type => 'service')) {
$ret .= 'Perform/save failed for hookScript';
}
if (!$db->set_prop($dbkey, 'hostOverride', $c->param('hostOverride'), type => 'service')) {
$ret .= 'Perform/save failed for hostOverride';
}
if (!$db->set_prop($dbkey, 'ACCEPT_TERMS', $c->param('ACCEPT_TERMS'), type => 'service')) {
$ret .= 'Perform/save failed for ACCEPT_TERMS';
}
if (!$db->set_prop($dbkey, 'API', $c->param('API'), type => 'service')) { $ret .= 'Perform/save failed for API'; }
if (!$db->set_prop($dbkey, 'keysize', $c->param('keysize'), type => 'service')) {
$ret .= 'Perform/save failed for keysize';
}
if (!$db->set_prop($dbkey, 'configure', $c->param('configure'), type => 'service')) {
$ret .= 'Perform/save failed for configure';
}
if (!$db->set_prop($dbkey, 'email', $c->param('email'), type => 'service')) {
$ret .= 'Perform/save failed for email';
}
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub perform_PARAMS
sub perform_CHECKALLDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (!TRUE
) #copy or perform with value: AllDomainsCheck e.g. $db->set_prop($dbkey,'AllDomainsCheck',$c->param('AllDomainsCheck'),type=>'service'))
{
$ret .= 'Perform/save failed for AllDomainsCheck';
} ## end if (!TRUE)
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub perform_CHECKALLDOMAINS
sub perform_CHECKALLENABLEDDOMAINS {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (!TRUE
) #copy or perform with value: EnabledDomainsCheck e.g. $db->set_prop($dbkey,'EnabledDomainsCheck',$c->param('EnabledDomainsCheck'),type=>'service'))
{
$ret .= 'Perform/save failed for EnabledDomainsCheck';
} ## end if (!TRUE)
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub perform_CHECKALLENABLEDDOMAINS
sub perform_CHECKONEDOMAIN {
my $c = shift;
my $prefix_data = shift; #Data hash as parameter
my $ret = "";
my $db = $cdb; #maybe one of the others
my $dbkey = 'ChangeThis';
if (!TRUE
) #copy or perform with value: OneDomainToCheck e.g. $db->set_prop($dbkey,'OneDomainToCheck',$c->param('OneDomainToCheck'),type=>'service'))
{
$ret .= 'Perform/save failed for OneDomainToCheck';
} ## end if (!TRUE)
if (!TRUE
) #copy or perform with value: OneDomainsCheck e.g. $db->set_prop($dbkey,'OneDomainsCheck',$c->param('OneDomainsCheck'),type=>'service'))
{
$ret .= 'Perform/save failed for OneDomainsCheck';
} ## end if (!TRUE)
if ($ret eq "") { $ret = 'ok'; }
return $ret;
} ## end sub perform_CHECKONEDOMAIN
sub create_link {
# WIP
my ($c, $route, $panel, $index) = @_;
my $link = "$route?trt=$panel&Selected=$index";
return $link;
} ## end sub create_link
sub get_my_ip {
my ($self, $item, $prop, $default) = @_;
my $output = `/usr/sbin/e-smith/getmyip`;
return $output || "IP";
} ## end sub get_my_ip
sub update_one_domain {
my ($self, $domain) = @_;
return "$domain not domain" unless ($ddb->get($domain) || $hdb->get($domain));
($domain) = ($domain =~ /([\w\p{L}.]+)/);
my $output = `/etc/e-smith/events/actions/letsencrypt-setdomains " " $domain `;
return $output || "-empty-";
} ## end sub update_one_domain
sub update_all_domains {
my $self = shift;
my $output = `/etc/e-smith/events/actions/letsencrypt-setdomains "" "" all `;
return $output || "-empty-";
} ## end sub update_all_domains
sub update_enabled_domains {
my $self = shift;
my $output = `/etc/e-smith/events/actions/letsencrypt-setdomains "" "" enabled `;
return $output || "-empty-";
} ## end sub update_enabled_domains
1;

View File

@@ -1,448 +0,0 @@
package SrvMngr::Controller::Letsencrypt;
#
# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
#
#----------------------------------------------------------------------
# heading : Network
# description : Letsencrypt certificate
# navigation : 6000 6600
#
# name : letsencrypt, method : get, url : /letsencrypt, ctlact : Letsencrypt#main
# name : letsencryptu, method : post, url : /letsencryptu, ctlact : Letsencrypt#do_update
# name : letsencryptd, method : get, url : /letsencryptd, ctlact : Letsencrypt#do_display
#
# routes : end
#
# Documentation: https://wiki.contribs.org/Letsencrypt
#----------------------------------------------------------------------
#
# Scheme of things:
#
# TBA!!
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use constant FALSE => 0;
use constant TRUE => 1;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use Data::Dumper;
use esmith::util;
use esmith::util::network;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::NetworksDB;
use esmith::HostsDB;
use esmith::DomainsDB;
require
'/usr/share/smanager/lib/SrvMngr/Controller/Letsencrypt-Custom.pm'; #The code that is to be added by the developer
sub main {
#
# Initial entry - route is "/<whatever>"
#
#set initial panel
#for initial panel:
#Specifiy panel to enter
#load up _data hash with DB fields
#load up stash with pointer(s) to control fields hash(= get-))
#and a pointer to the prefix_data hash
#render initial panel
my $c = shift;
$c->app->log->info($c->log_req);
#The most common ones
my $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
my $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
my $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
my $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
my %lets_data = ();
my $title = $c->l('lets_Letsencrypt_certificate');
my $modul = '';
$lets_data{'trt'} = 'LIST';
#Load any DB entries into the <prefix>_data area so as they are preset in the form
# which DB - this only really works if the initial panel is a PARAMS type panel and not a TABLE
my $db = $cdb; #pickup local or global db or Default to config
$c->do_display($lets_data{'trt'});
} ## end sub main
# Post request with params - submit from the form
sub do_update {
#
# Return after submit pushed on panel (this is a post) - route is "/<whatever>u"
# parameters in the params hash.
#
#load up all params into prefix_data hash:
#By panel (series of if statements - only one executed):
#call validate-PANEL() - return ret = ok or error message
#if validation not ok:
#render back to current panel with error message in stash
#otherwise:
#By panel (series of if statements - only one executed):
#do whatever is required: call perform-PANEL() - return "ok" or Error Message
#call signal-event for any global actions specified (check it exists - error and continue?)
#if action smeserver-<whatever>-update exists
#signal_event smeserver-<whatever>-update
#call signal-event for any specific actions for thids panel (check it exists first - error and continue)
#set success in stash
#if no "nextpanel" entry:
#set firstpanel
#else
#set nextpanel
#call render
my $c = shift;
$c->app->log->info($c->log_req);
my $modul = '';
#The most common ones - you might want to comment out any not used.
my $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
my $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
my $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
my $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
my %lets_data = ();
my $title = $c->l('lets_Letsencrypt_certificate');
# Accessing all POST parameters
my %params = $c->req->params->to_hash;
# Get number of POST parameters
my $num_params = keys %params;
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $lets_data{$key} = $value;
#}
# the value of trt will tell you which panel has returned
my $trt = $c->param('trt') || 'LIST'; #hidden control on every form.
my $ret = 'ok';
#Validate the parameters in a custom sub one for each panel (although only one of these will be executed)
my $thispanel;
if ($trt eq 'LIST') {
#Validate form parameters for panel LIST
$ret = $c->validate_LIST(\%lets_data);
$thispanel = 'LIST';
} ## end if ($trt eq 'LIST')
if ($trt eq 'PARAMS') {
#Validate form parameters for panel PARAMS
$ret = $c->validate_PARAMS(\%lets_data);
$thispanel = 'PARAMS';
} ## end if ($trt eq 'PARAMS')
if ($trt eq 'CHECKALLDOMAINS') {
#Validate form parameters for panel CHECKALLDOMAINS
$ret = $c->validate_CHECKALLDOMAINS(\%lets_data);
$thispanel = 'CHECKALLDOMAINS';
} ## end if ($trt eq 'CHECKALLDOMAINS')
if ($trt eq 'CHECKALLENABLEDDOMAINS') {
#Validate form parameters for panel CHECKALLENABLEDDOMAINS
$ret = $c->validate_CHECKALLENABLEDDOMAINS(\%lets_data);
$thispanel = 'CHECKALLENABLEDDOMAINS';
} ## end if ($trt eq 'CHECKALLENABLEDDOMAINS')
if ($trt eq 'CHECKONEDOMAIN') {
#Validate form parameters for panel CHECKONEDOMAIN
$ret = $c->validate_CHECKONEDOMAIN(\%lets_data);
$thispanel = 'CHECKONEDOMAIN';
} ## end if ($trt eq 'CHECKONEDOMAIN')
if ($ret ne "ok") {
$c->do_display($thispanel);
} else {
#Do whatever is needed, including writing values to the DB
if ($trt eq 'LIST') {
#do whatever is required ...
$ret = $c->perform_LIST(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash(success => $c->l('lets_LIST_panel_action_was_successful'))
; #A bit bland - edit it in the lex file
}
} ## end if ($trt eq 'LIST')
if ($trt eq 'PARAMS') {
#do whatever is required ...
$ret = $c->perform_PARAMS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash(success => $c->l('lets_PARAMS_panel_action_was_successful'))
; #A bit bland - edit it in the lex file
}
} ## end if ($trt eq 'PARAMS')
if ($trt eq 'CHECKALLDOMAINS') {
#do whatever is required ...
$ret = $c->perform_CHECKALLDOMAINS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash(success => $c->l('lets_CHECKALLDOMAINS_panel_action_was_successful'))
; #A bit bland - edit it in the lex file
}
} ## end if ($trt eq 'CHECKALLDOMAINS')
if ($trt eq 'CHECKALLENABLEDDOMAINS') {
#do whatever is required ...
$ret = $c->perform_CHECKALLENABLEDDOMAINS(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash(success => $c->l('lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful'))
; #A bit bland - edit it in the lex file
}
} ## end if ($trt eq 'CHECKALLENABLEDDOMAINS')
if ($trt eq 'CHECKONEDOMAIN') {
#do whatever is required ...
$ret = $c->perform_CHECKONEDOMAIN(\%lets_data);
if ($ret ne "ok") {
# return to the panel with error message
$c->stash(error => $c->l($ret));
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} else {
$c->stash(success => $c->l('lets_CHECKONEDOMAIN_panel_action_was_successful'))
; #A bit bland - edit it in the lex file
}
} ## end if ($trt eq 'CHECKONEDOMAIN')
# and call any signal-events needed
#TBD
# Setup shared data and call panel
if ('none' eq 'none') {
$lets_data{'trt'} = 'LIST';
} else {
$lets_data{'trt'} = 'none';
}
$c->do_display($lets_data{'trt'});
} ## end else [ if ($ret ne "ok") ]
} ## end sub do_update
sub do_display {
#
# Return after link clicked in table (this is a get) - route is "/<whatever>d"
# Expects ?trt=PANEL&selected="TableRowName" plus any other required
#
# OR it maybe a post from the main panel to add a new record
#
#load up all supplied params into prefix_data hash
#call get-selected-PANEL() - returns hash of all relevent parameters
#load up returned hash into prefix_data
#render - to called panel
my ($c, $trt) = @_;
$c->app->log->info($c->log_req);
#The most common ones - you might want to comment out any not used.
my $cdb = esmith::ConfigDB->open() || die("Couldn't open config db");
my $adb = esmith::AccountsDB->open() || die("Couldn't open Accounts db");
my $ndb = esmith::NetworksDB->open() || die("Couldn't open Network db");
my $hdb = esmith::HostsDB->open() || die("Couldn't open Hosts db");
my $ddb = esmith::DomainsDB->open() || die("Couldn't open Domains db");
my %lets_data = ();
my $title = $c->l('lets_Letsencrypt_certificate');
my $modul = "";
# Accessing all parameters
my $params = $c->req->params->to_hash;
# Get number of parameters
my $num_params = scalar keys %$params;
#Tag as Post or Get (ie. create new entry or edit existing one
my $is_new_record = ($c->req->method() eq 'POST');
#Params are available in the hash "params" - copy to the prefix_data hash
#while (my ($key, $value) = each %{$c->req->params->to_hash}) {
# $lets_data{$key} = $value;
#}
# the value of trt will tell you which panel has returned
if (!$trt) {
$trt = $c->param('trt') || 'LIST'; #Indicates where to go now
}
# Now add in the params from the selected row from the table
my %selectedrow;
if ($trt eq 'LIST') {
#Validate Get selected row (if applicable) LIST
%selectedrow = $c->get_selected_LIST($lets_data{'Selected'}, $is_new_record);
} ## end if ($trt eq 'LIST')
if ($trt eq 'PARAMS') {
#Validate Get selected row (if applicable) PARAMS
%selectedrow = $c->get_selected_PARAMS($lets_data{'Selected'}, $is_new_record);
} ## end if ($trt eq 'PARAMS')
if ($trt eq 'CHECKALLDOMAINS') {
#Validate Get selected row (if applicable) CHECKALLDOMAINS
%selectedrow = $c->get_selected_CHECKALLDOMAINS($lets_data{'Selected'}, $is_new_record);
} ## end if ($trt eq 'CHECKALLDOMAINS')
if ($trt eq 'CHECKALLENABLEDDOMAINS') {
#Validate Get selected row (if applicable) CHECKALLENABLEDDOMAINS
%selectedrow = $c->get_selected_CHECKALLENABLEDDOMAINS($lets_data{'Selected'}, $is_new_record);
} ## end if ($trt eq 'CHECKALLENABLEDDOMAINS')
if ($trt eq 'CHECKONEDOMAIN') {
#Validate Get selected row (if applicable) CHECKONEDOMAIN
%selectedrow = $c->get_selected_CHECKONEDOMAIN($lets_data{'Selected'}, $is_new_record);
} ## end if ($trt eq 'CHECKONEDOMAIN')
#Copy in the selected row params to the prefix_data hash to pass to the panel
while (my ($key, $value) = each %selectedrow) {
$lets_data{$key} = $value;
}
# Where to go now
$lets_data{'trt'} = $trt;
# Set up other shared data according to the panel to go to
if ($trt eq 'LIST') {
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_LIST();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
} ## end if ($trt eq 'LIST')
if ($trt eq 'PARAMS') {
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_PARAMS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
} ## end if ($trt eq 'PARAMS')
if ($trt eq 'CHECKALLDOMAINS') {
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_CHECKALLDOMAINS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
} ## end if ($trt eq 'CHECKALLDOMAINS')
if ($trt eq 'CHECKALLENABLEDDOMAINS') {
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_CHECKALLENABLEDDOMAINS();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
} ## end if ($trt eq 'CHECKALLENABLEDDOMAINS')
if ($trt eq 'CHECKONEDOMAIN') {
# pickup any other contents needed and load them into hash shared with panel
my %returned_hash;
# subroutine returns a hash directly
%returned_hash = $c->get_data_for_panel_CHECKONEDOMAIN();
# Copy each key-value pair from the returned hash to the prefix data hash
while (my ($key, $value) = each %returned_hash) {
$lets_data{$key} = $value;
}
} ## end if ($trt eq 'CHECKONEDOMAIN')
# and table control fields
$c->stash(DomainList => $c->get_DomainList());
# Data for panel
$c->stash(
title => $title,
modul => $modul,
lets_data => \%lets_data
);
$c->render(template => "letsencrypt");
} ## end sub do_display
1;

View File

@@ -13,13 +13,12 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session subnet_mask get_reg_mask ip_number);
#use Data::Dumper;
use esmith::util;
use esmith::HostsDB;
#my $network_db = esmith::NetworksDB->open() || die("Couldn't open networks db");
use esmith::HostsDB::UTF8;
use esmith::NetworksDB::UTF8;
use esmith::ConfigDB::UTF8;
my $ret = "OK";
my ($network_db);
our ($network_db,$config_db);
sub main {
my $c = shift;
@@ -27,7 +26,7 @@ sub main {
my %ln_datas = ();
$ln_datas{return} = "";
my $title = $c->l('ln_LOCAL NETWORKS');
$network_db = esmith::NetworksDB->open() || die("Couldn't open networks db");
$network_db = esmith::NetworksDB::UTF8->open() || die("Couldn't open networks db");
my $modul = '';
$ln_datas{trt} = 'LIST';
my @localnetworks;
@@ -49,7 +48,7 @@ sub do_display {
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
$network_db = esmith::NetworksDB->open() || die("Couldn't open networks db");
$network_db = esmith::NetworksDB::UTF8->open() || die("Couldn't open networks db");
$trt = 'DEL' if ($rt eq 'localnetworksdel');
$trt = 'ADD' if ($rt eq 'localnetworksadd');
$trt = 'ADD1' if ($rt eq 'localnetworksadd1');
@@ -68,23 +67,23 @@ sub do_display {
#Add a network - called after new network details filled in
my %ret = add_network($c);
$network_db = esmith::NetworksDB::UTF8->open();
#Return to list page if success
if ((index($ret{ret}, "SUCCESS") != -1)) {
$trt = "LIST";
} else {
#Error - return to Add page
$trt = "ADD";
}
$network_db = esmith::NetworksDB->open() || die("Failed to open Networkdb-3"); #Refresh the network DB
#$network_db = esmith::NetworksDB::UTF8->open() || die("Failed to open Networkdb-3"); #Refresh the network DB
$c->stash(ret => \%ret); #stash it away for the template
} ## end if ($trt eq 'ADD1')
if ($trt eq 'DEL1') {
#After Remove clicked on Delete network panel
$network_db = esmith::NetworksDB->open() || die("Failed to open Networkdb-1");
#$network_db = esmith::NetworksDB::UTF8->open() || die("Failed to open Networkdb-1");
my $localnetwork = $c->param("localnetwork");
my $delete_hosts = $c->param("deletehost") || "1"; #default to deleting them.
my $rec = $network_db->get($localnetwork) || die("Failed to find network on db:$localnetwork");
@@ -93,7 +92,7 @@ sub do_display {
$ln_datas{localnetwork} = $localnetwork;
}
my %ret = remove_network($localnetwork, $delete_hosts);
$network_db = esmith::NetworksDB->open() || die("Failed to open Networkdb-2"); #Refresh the network DB
#$network_db = esmith::NetworksDB::UTF8->open() || die("Failed to open Networkdb-2"); #Refresh the network DB
my @localnetworks;
if ($network_db) {
@@ -138,7 +137,7 @@ sub do_display {
sub remove_network {
my $network = shift;
$network_db = esmith::NetworksDB->open();
$network_db = esmith::NetworksDB::UTF8->open();
my $record = $network_db->get($network);
my $delete_hosts = shift;
@@ -174,7 +173,7 @@ sub hosts_on_network {
my $netmask = shift;
die if not $network and $netmask;
my $cidr = "$network/$netmask";
my $hosts = esmith::HostsDB->open() || die("Couldn't open hosts db");
my $hosts = esmith::HostsDB::UTF8->open() || die("Couldn't open hosts db");
my @localhosts = grep { $_->prop('HostType') eq 'Local' } $hosts->hosts;
my @hosts_on_network = ();
@@ -207,9 +206,9 @@ sub add_network {
# we transform bit mask to regular mask
$networkMask = get_reg_mask($networkAddress, $networkMask);
my $network_db = esmith::NetworksDB->open()
|| esmith::NetworksDB->create();
my $config_db = esmith::ConfigDB->open();
my $network_db = esmith::NetworksDB::UTF8->open()
|| esmith::NetworksDB::UTF8->create();
my $config_db = esmith::ConfigDB::UTF8->open();
my $localIP = $config_db->get('LocalIP');
my $localNetmask = $config_db->get('LocalNetmask');
my ($localNetwork, $localBroadcast)
@@ -222,17 +221,18 @@ sub add_network {
# in the form itself, but it just seemed too fiddly to do that
# at the moment. -- Skud 2002-04-11
# I agree --bjr 2020-04-18
if ($routerNetwork ne $localNetwork) {
return (ret => 'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK');
}
my ($network, $broadcast) = esmith::util::computeNetworkAndBroadcast($networkAddress, $networkMask);
if ($routerNetwork ne $localNetwork) {
return (ret => 'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK', vars => "$network,$networkMask,$networkRouter");
}
if ($network eq $localNetwork) {
return (ret => 'ln_NETWORK_ALREADY_LOCAL');
return (ret => 'ln_NETWORK_ALREADY_LOCAL', vars => "$network,$networkMask,$networkRouter");
}
if ($network_db->get($network)) {
return (ret => 'ln_NETWORK_ALREADY_ADDED');
return (ret => 'ln_NETWORK_ALREADY_ADDED', vars => "$network,$networkMask,$networkRouter");
}
$network_db->new_record(
$network,
@@ -246,7 +246,7 @@ sub add_network {
$network =~ /(.+)/;
$network = $1;
system("/sbin/e-smith/signal-event", "network-create", $network) == 0
or (return (ret => 'ln_ERROR_CREATING_NETWORK'));
or (return (ret => 'ln_ERROR_CREATING_NETWORK', vars => "$network,$networkMask,$networkRouter"));
my ($totalHosts, $firstAddr, $lastAddr) = esmith::util::computeHostRange($network, $networkMask);
my $msg;
@@ -268,4 +268,4 @@ sub add_network {
);
} ## end else [ if ($totalHosts == 1) ]
} ## end sub add_network
1;
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Login;
#----------------------------------------------------------------------
# heading : Support
# description : Login
# navigation : 0000 001
# navigation : 0 200
# menu : N
#
# routes : end
@@ -18,7 +18,7 @@ use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use esmith::AccountsDB;
use esmith::AccountsDB::UTF8;
use SrvMngr::I18N;
use SrvMngr::Model::Main;
use SrvMngr qw( theme_list init_session );
@@ -26,7 +26,7 @@ my $MAX_LOGIN_ATTEMPTS = 3;
my $DURATION_BLOCKED = 30 * 60; # access blocked for 30 min
my $TIMEOUT_FAILED_LOGIN = 1;
my $RESET_DURATION = 2 * 60 * 60; # 2 hours for resetting
our $adb = esmith::AccountsDB->open() or die "Couldn't open DB Accounts\n";
our $adb;
my $allowed_user_re = qr/^\w{5,10}$/;
my %Login_Attempts;
@@ -39,6 +39,7 @@ sub main {
sub login {
my $c = shift;
my $trt = $c->param('Trt');
$adb = esmith::AccountsDB::UTF8->open() or die "Couldn't open DB Accounts\n";
# password reset request
if ($trt eq 'RESET') {
@@ -85,13 +86,13 @@ sub login {
$c->session(logged_in => 1); # set the logged_in flag
$c->session(username => $name); # keep a copy of the username
# if ( $name eq 'admin' || $adb->is_user_in_group($name, 'AdmiN') ) # for futur use
# if ( $name eq 'admin' || $adb->is_user_in_group($name, 'Admin') ) # for futur use
if ($name eq 'admin') {
$c->session(is_admin => 1);
} else {
$c->session(is_admin => 0);
}
$c->session(expiration => 600); # expire this session in 10 minutes
$c->session(expiration => $c->config->{timeout} ); # expire this session in the time set in config
$c->flash(success => $c->l('use_WELCOME'));
record_login_attempt($c, 'SUCCESS');
} else {
@@ -114,6 +115,7 @@ sub mail_rescue {
my $c = shift;
my $name = $c->param('Username');
my $from = $c->param('From');
$adb = esmith::AccountsDB::UTF8->open() or die "Couldn't open DB Accounts\n";
my $res;
$res .= $c->l('use_TOO_MANY_LOGIN') if (is_denied($c));

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Logout;
#----------------------------------------------------------------------
# heading : Current User
# description : Logout
# navigation : 1000 900
# navigation : 1000 1000
# menu : U
#
# routes : end

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Manual;
#----------------------------------------------------------------------
# heading : Support
# description : Online manual
# navigation : 0000 100
# navigation : 0 300
# menu : N
#
# routes : end

View File

@@ -13,14 +13,10 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#use Regexp::Common qw /net/;
#use Data::Dumper;
use esmith::util;
use esmith::HostsDB;
#our $db = esmith::ConfigDB->open || die "Can't open configuration database: $!\n";
#our $tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
#our $udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
use esmith::ConfigDB::UTF8;
my ($cdb,$tcp_db,$udp_db);
my %ret = ();
@@ -34,9 +30,9 @@ sub main {
$pf_datas{return} = "";
my $title = $c->l('pf_FORM_TITLE');
my $modul = '';
$cdb = esmith::ConfigDB->open || die "Can't open configuration database: $!\n";
$tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
$tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$pf_datas{trt} = 'LIST';
my @tcpforwards = $tcp_db->get_all;
my @udpforwards = $udp_db->get_all;
@@ -57,9 +53,9 @@ sub do_display {
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $cdb = esmith::ConfigDB->open || die "Can't open configuration database: $!\n";
my $tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
my $udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
my $cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
my $tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
my $udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$trt = 'DEL' if ($rt eq 'portforwardingdel');
$trt = 'ADD' if ($rt eq 'portforwardingadd');
$trt = 'ADD1' if ($rt eq 'portforwardingadd1');
@@ -142,6 +138,10 @@ sub do_display {
if ($trt eq 'LIST') {
#List all the port forwards
# Open them again as maybe written to above
$tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
my @tcpforwards = $tcp_db->get_all;
my @udpforwards = $udp_db->get_all;
my $empty = 1 if not @tcpforwards and not @udpforwards;
@@ -168,10 +168,10 @@ sub add_portforward {
my $fdb;
if ($proto eq 'TCP') {
$tcp_db = esmith::ConfigDB->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$tcp_db = esmith::ConfigDB::UTF8->open('portforward_tcp') || die "Can't open portforward_tcp database: $!\n";
$fdb = $tcp_db;
} else {
$udp_db = esmith::ConfigDB->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$udp_db = esmith::ConfigDB::UTF8->open('portforward_udp') || die "Can't open portforward_udp database: $!\n";
$fdb = $udp_db;
}
@@ -211,6 +211,7 @@ sub add_portforward {
sub get_destination_host {
my $q = shift;
$cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
my $dhost = $q->param("dhost");
my $localip = $cdb->get_prop('InternalInterface', 'IPAddress');
my $external_ip = $cdb->get_prop('ExternalInterface', 'IPAddress') || $localip;
@@ -357,6 +358,7 @@ sub isValidPort() {
sub validate_destination_host {
my $c = shift;
$cdb = esmith::ConfigDB::UTF8->open || die "Can't open configuration database: $!\n";
my $dhost = $c->param('dhost');
$dhost =~ s/^\s+|\s+$//g;
my $localip = $cdb->get_prop('InternalInterface', 'IPAddress');

View File

@@ -14,15 +14,15 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
my $adb;
use esmith::AccountsDB::UTF8;
our $adb;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %prt_datas = ();
my $title = $c->l('prt_FORM_TITLE');
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$prt_datas{'trt'} = 'LIST';
my @printerDrivers;
@@ -38,7 +38,7 @@ sub do_display {
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LIST');
my $printer = $c->param('printer') || '';
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
#$trt = 'DEL' if ( $printer );
#$trt = 'ADD' if ( $rt eq 'printeradd' );
@@ -79,7 +79,7 @@ sub do_update {
my $trt = ($c->param('trt') || 'LIST');
my %prt_datas = ();
my $title = $c->l('prt_FORM_TITLE');
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$prt_datas{'trt'} = $trt;
my ($res, $result) = '';

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Proxy;
#----------------------------------------------------------------------
# heading : System
# description : Proxy settings
# navigation : 4000 710
# navigation : 4000 200
#----------------------------------------------------------------------
#
# routes : end
@@ -14,11 +14,14 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
our $db = esmith::ConfigDB->open || die "Couldn't open config db";
use esmith::ConfigDB::UTF8;
our $db;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %prx_datas = ();
my $title = $c->l('prx_TITLE');
my $modul = $c->render_to_string(inline => $c->l('prx_FIRST_PAGE_DESCRIPTION'));
@@ -40,6 +43,7 @@ sub do_update {
my $http_proxy_status = $c->param('http_proxy_status') || 'disabled';
my $smtp_proxy_status = $c->param('smtp_proxy_status') || '';
my $result = "";
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my $squid = $db->get('squid') or $result = $c->l('prx_ERR_NO_SQUID_REC');
# smtpd is allowed to not exist, as the relevant packages may not be
@@ -51,10 +55,10 @@ sub do_update {
# Update the system
#
system("/sbin/e-smith/signal-event proxy-update") == 0
or $result = $c->l('prx_ERR_PROXY_UPDATE_FAILED');
or $result = $c->l('prx_ERR_PROXY_UPDATE_FAILED');
my $title = $c->l('prx_TITLE');
if ($result eq '') { $result = $c->l('prx_SUCCESS'); }
$c->stash(title => $title, modul => $result);
$c->render(template => 'module');
} ## end sub do_update
1;
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Pseudonyms;
#----------------------------------------------------------------------
# heading : User management
# description : Pseudonyms
# navigation : 2000 210
# navigation : 2000 300
#----------------------------------------------------------------------
#
# routes : end
@@ -14,15 +14,10 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::AccountsDB::UTF8;
use esmith::DomainsDB::UTF8;
#use Data::Dumper;
#use esmith::FormMagick::Panel::pseudonyms;
use esmith::AccountsDB;
#use URI::Escape;
#our $cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
my ($cdb,$adb);
our ($cdb,$adb);
sub main {
my $c = shift;
@@ -32,8 +27,7 @@ sub main {
my $notif = '';
$pse_datas{trt} = 'LST';
my @pseudonyms;
#$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
if ($adb) {
@pseudonyms = $adb->pseudonyms();
@@ -50,8 +44,7 @@ sub do_display {
my $pseudonym = $c->param('pseudonym') || '';
my $title = $c->l('pse_FORM_TITLE');
my %pse_datas = ();
#$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$pse_datas{'trt'} = $trt;
if ($trt eq 'ADD') {
@@ -97,8 +90,7 @@ sub do_update {
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'LST');
my $title = $c->l('pse_FORM_TITLE');
#$cdb = esmith::ConfigDB->open || die "Couldn't open configuration db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my %pse_datas = ();
$pse_datas{'trt'} = $trt;
my ($res, $result) = '';
@@ -331,8 +323,7 @@ sub validate_new_pseudonym_name {
if (defined $acct) {
return ($c->l('pse_NAME_IN_USE'));
} elsif ($pseudonym =~ /@/) {
use esmith::DomainsDB;
my $ddb = esmith::DomainsDB->open_ro
my $ddb = esmith::DomainsDB::UTF8->open_ro
or die "Couldn't open DomainsDB\n";
my ($lhs, $rhs) = split /@/, $pseudonym;
return ($c->l('pse_PSEUDONYM_INVALID_DOMAIN')) unless ($ddb->get($rhs));

View File

@@ -14,6 +14,9 @@ use SrvMngr qw(gen_locale_date_string);
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use List::Util qw(sum);
#use Mail::Log::Trace::Postfix;
sub main {
my $c = shift;
@@ -48,44 +51,66 @@ sub generateReport {
my $c = shift;
my $report_type = shift;
my $out = '';
#------------------------------------------------------------
# Looks good; go ahead and generate the report.
# Go ahead and generate the report.
#------------------------------------------------------------
# $| = 1;
my $now_string = $c->gen_locale_date_string();
my $log_path = '/var/log/maillog';
$out .= sprintf("<h3>%s %s </h3>", $c->l('REPORT_GENERATED'), $now_string);
if ($report_type =~ /^qmail-q/) {
open(QMAILQUEUEREPORT, "/var/qmail/bin/$report_type |");
$out .= sprintf "<pre>";
while (<QMAILQUEUEREPORT>) {
$out .= sprintf("%s", $_);
}
close QMAILQUEUEREPORT;
$out .= sprintf "</pre>";
$out .= sprintf("<h3>%s</h3>", $c->l('END_OF_REPORT'));
return '';
} ## end if ($report_type =~ /^qmail-q/)
chdir "/var/log/qmail";
open(QMAILANALOG,
"/bin/cat \@* current 2>/dev/null"
. "| /usr/local/bin/tai64nunix"
. "| /usr/local/qmailanalog/bin/matchup 5>/dev/null"
. "| /usr/local/qmailanalog/bin/$report_type |");
$out .= sprintf "<pre>";
# Get the selected report from the form submission
my $selected_report = $report_type;
while (<QMAILANALOG>) {
# Call the relevant report sub based on the selection
if ($selected_report eq 'daily_summary') {
$out .= daily_summary_report($log_path);
}
elsif ($selected_report eq 'daily_summary_today') {
$out .= daily_summary_report_today($log_path);
}
elsif ($selected_report eq 'daily_summary_all') {
$out .= daily_summary_report_all($log_path);
}
elsif ($selected_report eq 'top_senders') {
$out .= top_senders_and_recipients($log_path);
}
elsif ($selected_report eq 'bounce_analysis') {
$out .= bounce_rate_analysis($log_path);
}
elsif ($selected_report eq 'spam_and_virus') {
$out .= spam_and_virus_filter_report($log_path);
}
elsif ($selected_report eq 'delivery_status') {
$out .= delivery_status_report($log_path);
}
elsif ($selected_report eq 'geo_analysis') {
$out .= geographical_analysis_of_email($log_path);
}
elsif ($selected_report eq 'traffic_analysis') {
$out .= traffic_analysis($log_path);
}
elsif ($selected_report eq 'auth_analysis') {
$out .= authentication_analysis($log_path);
}
elsif ($selected_report eq 'user_activity') {
$out .= user_activity_report($log_path);
}
elsif ($selected_report eq 'error_reporting') {
$out .= error_reporting($log_path);
}
elsif ($selected_report eq 'comparison_reports') {
$out .= comparison_reports($log_path, '/var/log/mail.log.1');
}
elsif ($selected_report eq 'customized_reports') {
$out .= customized_reports($log_path);
}
else {
$out .= 'Invalid report selected';
}
# Cook any special HTML characters
s/\&/\&amp;/g;
s/\"/\&quot;/g;
s/\>/\&gt;/g;
s/\</\&lt;/g;
$out .= sprintf("%s", $_);
} ## end while (<QMAILANALOG>)
close QMAILANALOG;
# The $output variable now contains the generated report output.
# Further processing can be done here, or you can render it later.
$out .= sprintf "</pre>";
$out .= sprintf("<h3>%s</h3>", $c->l('END_OF_REPORT'));
return $out;
@@ -94,22 +119,243 @@ sub generateReport {
sub reportType_list {
my $c = shift;
my @array = (
# [ $c->l('qma_LIST_OUTGOING') => 'qmail-qread' ],
# [ $c->l('qma_SUMMARIZE_QUEUE') => 'qmail-qstat' ],
[ $c->l('qma_SUCCESSFUL_DELIVERY_DELAY') => 'zddist' ],
[ $c->l('qma_REASONS_DEFERRAL') => 'zdeferrals' ],
[ $c->l('qma_REASONS_FAILURE') => 'zfailures' ],
[ $c->l('qma_BASIC_STATS') => 'zoverall' ],
[ $c->l('qma_RECIP_STATS') => 'zrecipients' ],
[ $c->l('qma_RECIP_HOSTS') => 'zrhosts' ],
[ $c->l('qma_RECIP_ORDERED') => 'zrxdelay' ],
[ $c->l('qma_SENDER_STATS') => 'zsenders' ],
[ $c->l('qma_SENDMAIL_STYLE') => 'zsendmail' ],
[ $c->l('qma_REASONS_SUCCESS') => 'zsuccesses' ],
[ $c->l('qma_SENDER_UIDS') => 'zsuids' ]
);
[$c->l('qma_Daily_Summary_Report_yesterday') => 'daily_summary'],
[$c->l('qma_Daily_Summary_Report_today') => 'daily_summary_today'],
[$c->l('qma_Daily_Summary_Report_all') => 'daily_summary_all'],
#[$c->l('qma_Top Senders and Recipients') => 'top_senders'],
#[$c->l('qma_Bounce Rate Analysis') => 'bounce_analysis'],
#[$c->l('qma_Spam and Virus Filtering Report') => 'spam_and_virus'],
#[$c->l('qma_Delivery Status Report') => 'delivery_status'],
#[$c->l('qma_Geographic Analysis of Email') => 'geo_analysis'],
#[$c->l('qma_Traffic Analysis') => 'traffic_analysis'],
#[$c->l('qma_Authentication Analysis') => 'auth_analysis'],
#[$c->l('qma_User Activity Report') => 'user_activity'],
#[$c->l('qma_Error Reporting') => 'error_reporting'],
#[$c->l('qma_Comparison Reports') => 'comparison_reports'],
#[$c->l('qma_Customized Reports') => 'customized_reports'],
);
my @sorted_array = sort { $a->[0] cmp $b->[0] } @array;
return \@sorted_array;
} ## end sub reportType_list
1;
sub daily_summary_report {
my $log_file = shift; # Path to log file
my $output = qx(ls -1 /var/log/maillog* | xargs cat |pflogsumm -d yesterday --detail 0 --no-no-msg-size);
return format_as_html("Daily Summary Report", $output);
}
sub daily_summary_report_today {
my $log_file = shift; # Path to log file
my $output = qx(ls -1 /var/log/maillog* | xargs cat |pflogsumm -d today --detail 0 --no-no-msg-size);
return format_as_html("Daily Summary Report", $output);
}
sub daily_summary_report_all {
my $log_file = shift; # Path to log file
my $output = qx(ls -1 /var/log/maillog* | xargs cat |pflogsumm --detail 0 --no-no-msg-size);
return format_as_html("Summary Report across all logs", $output);
}
sub top_senders_and_recipients {
my $log_file = shift;
my $output = qx(pflogsumm --smtpd-stats $log_file);
return format_as_html("Top Senders and Recipients", $output);
}
sub bounce_rate_analysis {
my $log_file = shift;
my $output = qx(pflogsumm --bounce-detail 10 $log_file); # Show up to 10 bounce details
return format_as_html("Bounce Rate Analysis", $output);
}
sub spam_and_virus_filter_report {
my $log_file = shift;
my $output = qx(pflogsumm -u 10 $log_file); # User report with up to 10 entries
return format_as_html("Spam and Virus Filtering Report", $output);
}
sub delivery_status_report {
my $log_file = shift;
my $output = qx(pflogsumm --deferral-detail 10 $log_file); # Show deferral details
return format_as_html("Delivery Status Report", $output);
}
sub geographical_analysis_of_email {
my $log_file = shift;
# `pflogsumm` doesn't have a specific option for geographic analysis in the help text;
# It's assumed this could be replaced with something relevant, like a SMTP detail.
my $output = qx(pflogsumm --smtp-detail 10 $log_file); # Show up to 10 SMTP details
return format_as_html("Geographic Analysis of Email", $output);
}
sub traffic_analysis {
my $log_file = shift;
my $output = qx(pflogsumm --verbose-msg-detail $log_file); # Request verbose detail
return format_as_html("Traffic Analysis", $output);
}
sub authentication_analysis {
my $log_file = shift;
my $output = qx(pflogsumm -u 10 --verbose-msg-detail $log_file); # User detailed report
return format_as_html("Authentication Analysis", $output);
}
sub user_activity_report {
my $log_file = shift;
my $output = qx(pflogsumm -u 20 $log_file); # Show user activity for up to 20 users
return format_as_html("User Activity Report", $output);
}
sub error_reporting {
my $log_file = shift;
my $output = qx(pflogsumm --problems-first $log_file); # This will show problems first
return format_as_html("Error Reporting", $output);
}
sub comparison_reports {
my ($log_file1, $log_file2) = @_; # Comparing two log files
my $output = qx(pflogsumm $log_file1 $log_file2); # Standard comparison without special flags
return format_as_html("Comparison Reports", $output);
}
sub customized_reports {
my $log_file = shift;
# Because we don't have a concrete custom flag, we'll consider using -d with specific detail.
my $output = qx(pflogsumm --detail 10 $log_file); # Generally show detailed summary
return format_as_html("Customized Reports", $output);
}
sub format_as_html {
my ($title, $content) = @_;
return <<HTML;
<h2>$title</h2>
<pre>$content</pre>
HTML
}
### 1. Message Tracking
#sub trace_message {
#my ($log_path, $message_id) = @_;
##my $tracer = Mail::Log::Trace::Postfix->new({log_file => $log_path});
##$tracer->set_message_id($message_id);
#my $output = "Message Tracking Report for ID: $message_id\n";
##$output .= "=" x 50 . "\n";
##$output .= sprintf "%-12s: %s\n", 'From', $tracer->get_from_address;
##$output .= sprintf "%-12s: %s\n", 'Status', $tracer->get_final_status;
##$output .= "\nRecipients:\n";
##$output .= join("\n", map { "- $_" } $tracer->get_recipient_addresses);
##$output .= "\n\nTimeline:\n";
##my $timeline = $tracer->get_timestamps;
##while (my ($stage, $time) = each %$timeline) {
##$output .= sprintf "%-10s: %s\n", ucfirst($stage), $time;
##}
#return $output || "No records found for message ID: $message_id";
#}
#### 2. Queue Analysis
#sub get_queue_stats {
#my $spool_dir = '/var/spool/postfix';
#my %queues = map { $_ => 0 } qw(active deferred bounce hold corrupt);
#foreach my $q (keys %queues) {
#opendir(my $dh, "$spool_dir/$q");
#$queues{$q} = scalar(grep { -f "$spool_dir/$q/$_" } readdir($dh));
#closedir($dh);
#}
#my $output = "Current Postfix Queue Status\n";
#$output .= "=" x 30 . "\n";
#$output .= sprintf "%-10s: %3d messages\n", ucfirst($_), $queues{$_}
#for sort keys %queues;
#$output .= "\nTotal: " . sum(values %queues) . " messages in queue";
#return $output;
#}
#### 3. Message Statistics
#sub get_message_stats {
#my ($log_path) = @_;
#my %stats = (received => 0, rejected => 0, delivered => 0,
#deferred => 0, bounced => 0, held => 0);
#open(my $fh, '<', $log_path);
#while(<$fh>) {
#$stats{received}++ if /qmgr.*: [A-Z0-9]+: from=/;
#$stats{delivered}++ if /status=sent/;
#$stats{rejected}++ if /NOQUEUE: reject/;
#$stats{deferred}++ if /status=deferred/;
#$stats{bounced}++ if /status=bounced/;
#$stats{held}++ if /status=hold/;
#}
#close($fh);
#my $output = "Message Statistics for " . localtime . "\n";
#$output .= "=" x 40 . "\n";
#$output .= sprintf "%-12s: %6d\n", 'Received', $stats{received};
#$output .= sprintf "%-12s: %6d (%.1f%%)\n", 'Delivered', $stats{delivered},
#($stats{received} ? ($stats{delivered}/$stats{received}*100) : 0);
#$output .= sprintf "%-12s: %6d\n", 'Rejected', $stats{rejected};
#$output .= sprintf "%-12s: %6d\n", 'Deferred', $stats{deferred};
#$output .= sprintf "%-12s: %6d\n", 'Bounced', $stats{bounced};
#$output .= sprintf "%-12s: %6d\n", 'Held', $stats{held};
#return $output;
#}
#### 4. User Activity Audit
#sub get_user_activity {
#my ($log_path, $email) = @_;
##my $tracer = Mail::Log::Trace::Postfix->new({log_file => $log_path});
##my $sent = scalar $tracer->find_messages_by_sender($email);
##my $received = scalar $tracer->find_messages_by_recipient($email);
#my $output = "Activity Report for: $email\n";
##$output .= "=" x (length($email) + 18) . "\n";
##$output .= "Messages sent: $sent\n";
##$output .= "Messages received: $received\n\n";
##$output .= "Last week's activity:\n";
##$output .= join("\n", map { sprintf "- %s: %d messages", $_->[0], $_->[1] }
##$tracer->get_weekly_stats($email));
#return $output || "No activity found for $email";
#}
#### 5. Security Monitoring
#sub detect_auth_failures {
#my ($log_path) = @_;
#my %failures;
#open(my $fh, '<', $log_path);
#while(<$fh>) {
#if(/SASL (?:LOGIN|PLAIN) authentication failed.*?\[([0-9.]+)\]/) {
#$failures{$1}++;
#}
#}
#close($fh);
#return "No authentication failures found" unless keys %failures;
#my $output = "Authentication Failure Report\n";
#$output .= "=" x 30 . "\n";
#$output .= sprintf "%-15s %s\n", 'IP Address', 'Attempts';
#$output .= sprintf "%-15s %s\n", '-' x 15, '-' x 7;
#foreach my $ip (sort { $failures{$b} <=> $failures{$a} } keys %failures) {
#$output .= sprintf "%-15s %5d\n", $ip, $failures{$ip};
#}
#$output .= "\nTotal failures: " . sum(values %failures);
#return $output;
#}
1;

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Quota;
#----------------------------------------------------------------------
# heading : User management
# description : Quotas
# navigation : 2000 300
# navigation : 2000 500
#----------------------------------------------------------------------
#
# routes : end
@@ -16,8 +16,8 @@ use Scalar::Util qw(looks_like_number);
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::AccountsDB::UTF8;
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
my $adb;
sub main {
@@ -25,7 +25,7 @@ sub main {
$c->app->log->info($c->log_req);
my %quo_datas = ();
my $title = $c->l('quo_FORM_TITLE');
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$quo_datas{'trt'} = 'LIST';
my @userAccounts;
@@ -44,7 +44,7 @@ sub do_display {
$trt = 'UPD' if ($user);
my %quo_datas = ();
my $title = $c->l('quo_FORM_TITLE');
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$quo_datas{'trt'} = $trt;
if ($trt eq 'UPD') {
@@ -73,7 +73,7 @@ sub do_update {
$quo_datas{trt} = $trt;
my $result = '';
my $res;
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
if ($trt eq 'UPD') {
$quo_datas{user} = ($c->param('user') || '');

View File

@@ -14,7 +14,7 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number subnet_mask get_reg_mask);
use esmith::ConfigDB;
use esmith::ConfigDB::UTF8;
use esmith::util;
use File::Basename;
use Exporter;
@@ -30,7 +30,7 @@ our @EXPORT = qw( networkAccess_list passwordLogin_list get_ssh_permit_root_logi
);
# get_pptp_sessions
our $db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
our $db;
sub main {
my $c = shift;
@@ -38,7 +38,7 @@ sub main {
my $title = $c->l('rma_FORM_TITLE');
my $notif = '';
my %rma_datas = ();
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
#$rma_datas{ipsecrwSess} = $c->get_ipsecrw_sessions();
#$rma_datas{pptpSessions} = $c->get_pptp_sessions();
@@ -60,7 +60,7 @@ sub do_action {
my $title = $c->l('rma_FORM_TITLE');
my ($result, $res, $trt) = '';
my %rma_datas = ();
$db = esmith::ConfigDB->open || warn "Couldn't open configuration database";
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
$rma_datas{ipsecrwSess} = ($c->param('IpsecrwSess') || '');
$rma_datas{ipsecrwReset} = ($c->param('IpsecrwReset') || '');
@@ -144,6 +144,7 @@ sub passwordLogin_list {
}
sub get_prop {
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my ($c, $item, $prop) = @_;
warn "You must specify a record key" unless $item;
warn "You must specify a property name" unless $prop;
@@ -154,6 +155,7 @@ sub get_prop {
sub get_value {
my $c = shift;
my $item = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
return ($db->get($item)->value());
} ## end sub get_value
@@ -179,8 +181,8 @@ sub get_ssh_password_auth {
}
sub get_ssh_access {
my $status = get_prop('', 'sshd', 'status');
my $c = shift;
my $status = $c->get_prop('sshd', 'status');
if (defined($status) && ($status eq 'enabled')) {
my $access = get_prop('', 'sshd', 'access');
$access = ($access eq 'public') ? 'public' : 'private';
@@ -202,6 +204,7 @@ sub get_ftp_password_login_access {
} ## end sub get_ftp_password_login_access
sub get_telnet_mode {
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $telnet = $db->get('telnet');
return ('off') unless $telnet;
my $status = $telnet->prop('status') || 'disabled';
@@ -211,8 +214,8 @@ sub get_telnet_mode {
} ## end sub get_telnet_mode
sub get_ipsecrw_sessions {
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $status = $db->get('ipsec')->prop('RoadWarriorStatus');
if (defined($status) && ($status eq 'enabled')) {
return ($db->get('ipsec')->prop('RoadWarriorSessions') || '0');
} else {
@@ -221,6 +224,7 @@ sub get_ipsecrw_sessions {
} ## end sub get_ipsecrw_sessions
sub get_ipsecrw_status {
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
return undef unless ($db->get('ipsec'));
return $db->get('ipsec')->prop('RoadWarriorStatus');
}
@@ -228,6 +232,7 @@ sub get_ipsecrw_status {
sub pptp_and_dhcp_range {
my $c = shift;
my $val = shift || 0;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $dhcp_status = $db->get_prop('dhcpd', 'status') || 'disabled';
my $dhcp_end = $db->get_prop('dhcpd', 'end') || '';
my $dhcp_start = $db->get_prop('dhcpd', 'start') || '';
@@ -245,6 +250,7 @@ sub pptp_and_dhcp_range {
sub _get_valid_from {
my $c = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $rec = $db->get('httpd-admin');
return undef unless ($rec);
my @vals = (split ',', ($rec->prop('ValidFrom') || ''));
@@ -287,12 +293,12 @@ sub validate_network_and_mask {
sub change_settings {
my ($c, %rma_datas) = @_;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
#------------------------------------------------------------
# good; go ahead and change the access.
#------------------------------------------------------------
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
my $rec = $db->get('telnet');
if ($rec) {
if ($rma_datas{telnetAccess} eq "off") {
$rec->set_prop('status', 'disabled');
@@ -363,7 +369,7 @@ sub change_settings {
sub set_ipsecrw_sessions {
my $c = shift;
my $sessions = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
if (defined $sessions) {
$db->get('ipsec')->set_prop('RoadWarriorSessions', $sessions);
@@ -378,6 +384,7 @@ sub add_new_valid_from {
my $c = shift;
my $net = shift;
my $mask = shift;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
# we transform bit mask to regular mask
$mask = get_reg_mask($net, $mask);
@@ -400,6 +407,7 @@ sub remove_valid_from {
my $c = shift;
my $remove_nets = shift;
my @remove = split /,/, $remove_nets;
$db = esmith::ConfigDB::UTF8->open || warn "Couldn't open configuration database";
# my @remove = $c->param('Remove_nets');
my @vals = $c->_get_valid_from();

View File

@@ -8,6 +8,8 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB::UTF8 qw(open_ro);
use esmith::AccountsDB::UTF8 qw(open_ro);
# retrieve a configuration db record
sub getconfig {
@@ -16,8 +18,7 @@ sub getconfig {
$c->app->log->info($c->log_req . ' ' . $key);
if ($key) {
use esmith::ConfigDB qw(open_ro);
my $cdb = esmith::ConfigDB->open_ro;
my $cdb = esmith::ConfigDB::UTF8->open_ro;
return getdb($c, $cdb, $key);
} ## end if ($key)
} ## end sub getconfig
@@ -29,8 +30,7 @@ sub getaccount {
$c->app->log->info($c->log_req . ' ' . $key);
if ($key) {
use esmith::AccountsDB qw(open_ro);
my $adb = esmith::AccountsDB->open_ro;
my $adb = esmith::AccountsDB::UTF8->open_ro;
return getdb($c, $adb, $key);
} ## end if ($key)
} ## end sub getaccount

View File

@@ -1,16 +1,11 @@
package SrvMngr::Controller::Review;
#----------------------------------------------------------------------
# heading : Support
# heading : Investigation
# description : Review configuration
# navigation : 000 500
# menu : N
# navigation : 7000 400
# routes : end
#----------------------------------------------------------------------
# heading-o : Configuration
# description-o : Review configuration
# navigation-o : 6000 6800
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
@@ -18,17 +13,20 @@ use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use SrvMngr qw(gen_locale_date_string);
use esmith::ConfigDB::UTF8;
use esmith::DomainsDB::UTF8;
use esmith::NetworksDB::UTF8;
#use SrvMngr::Review_sub qw(print_page);
#use smeserver::Panel::review;
our $db = esmith::ConfigDB->open_ro || die "Couldn't open config db";
our $domains = esmith::DomainsDB->open_ro || die "Couldn't open domains";
our $networks = esmith::NetworksDB->open_ro || die "Couldn't open networks";
our $db;
our $domains ;
our $networks;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $title = $c->l('rvw_FORM_TITLE');
my $modul = $c->render_to_string(inline => $c->l('rvw_DESCRIPTION'));
my %rvw_datas = ();
@@ -102,6 +100,7 @@ sub gen2_email_addresses {
sub gen2_domains {
my $c = shift;
$domains = esmith::DomainsDB::UTF8->open_ro || die "Couldn't open domains";
my @virtual = $domains->get_all_by_prop(type => 'domain');
my $numvirtual = @virtual;
@@ -130,6 +129,7 @@ serving. (mojo ver)
sub get2_local_networks {
my $c = shift;
$networks = esmith::NetworksDB::UTF8->open_ro || die "Couldn't open networks";
my @nets = $networks->get_all_by_prop('type' => 'network');
my $numNetworks = @nets;
@@ -152,6 +152,55 @@ sub get2_local_networks {
} ## end else [ if ($numNetworks == 0)]
} ## end sub get2_local_networks
sub get_net_prop {
my $fm = shift;
my $item = shift;
my $prop = shift;
$networks = esmith::NetworksDB::UTF8->open_ro || die "Couldn't open networks";
my $record = $networks->get($item);
if ($record) {
return $record->prop($prop);
}
else {
return '';
}
}
sub get_local_networks {
my $fm = shift;
$networks = esmith::NetworksDB::UTF8->open_ro || die "Couldn't open networks";
my @nets = $networks->get_all_by_prop('type' => 'network');
my $numNetworks = @nets;
if ($numNetworks == 0) {
return $fm->localise('NO_NETWORKS');
}
else {
my $out = "";
foreach my $network (sort @nets) {
if ($out ne "") {
$out .= "<BR>";
}
$out .= $network->key."/" . get_net_prop($fm, $network->key, 'Mask');
if ( defined get_net_prop($fm, $network->key, 'Router') ) {
$out .= " via " . get_net_prop ($fm, $network->key, 'Router');
}
}
return $out;
}
}
sub get_local_domain
{
return (get_value('','DomainName'));
}
=head2 print2_gateway_stanza
If this system is a server gateway, show the external ip and gateway ip (mojo ver)
@@ -217,4 +266,53 @@ sub print2_dhcp_stanza {
} ## end if (get_prop($c, 'dhcpd'...))
return $out;
} ## end sub print2_dhcp_stanza
sub get_value {
my $fm = shift;
my $item = shift;
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $record = $db->get($item);
if ($record) {
return $record->value();
}
else {
return '';
}
}
sub get_prop {
my $fm = shift if (ref($_[0]) ); # If we're being called in a formmagick context
# The first argument will always be a fm.
#otherwise, we don't want to grab it
my $item = shift;
my $prop = shift;
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $record = $db->get($item);
if ($record) {
return $record->prop($prop);
}
else {
return '';
}
}
sub get_public_ip_address
{
my $self = shift;
$db = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open config db";
my $sysconfig = $db->get('sysconfig');
if ($sysconfig)
{
my $publicIP = $sysconfig->prop('PublicIP');
if ($publicIP)
{
return $publicIP;
}
}
return undef;
}
1;

View File

@@ -1,9 +1,9 @@
package SrvMngr::Controller::Roundcubepanel;
#----------------------------------------------------------------------
# heading : System
# description : Roundcube webmail
# navigation : 99999 9999
# heading : Network
# description : Webmail
# navigation : 6000 900
#----------------------------------------------------------------------
#----------------------------------------------------------------------
# name : roundcubepanel, method : get, url : /roundcubepanel, ctlact : Roundcubepanel#main
@@ -21,10 +21,9 @@ use SrvMngr qw(theme_list init_session);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my $title = $c->l('Roundcube Webmail');
my $title = $c->l('Webmail');
my $roundcube_url = $c->param('url');
my $roundcube_height = $c->param('height') | 600;
$c->stash(title => $title, modul => $roundcube_url, height => $roundcube_height);
$c->stash(title => $title, modul => $roundcube_url);
$c->render(template => 'roundcube');
} ## end sub main

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Support;
#----------------------------------------------------------------------
# heading : Support
# description : Support and licensing
# navigation : 0000 200
# navigation : 0 400
# menu : N
#
# routes : end

View File

@@ -5,19 +5,18 @@ package SrvMngr::Controller::Swttheme;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use esmith::ConfigDB::UTF8;
#use SrvMngr qw(theme_list init_session);
our $db = esmith::ConfigDB->open() || die "Couldn't open config db";
sub main {
my $c = shift;
my $db = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $from = $c->param('From') || '/';
my $theme = $c->param('Theme');
$c->app->log->info(" swt theme '$from' '$theme' ");
my $oldTheme = $c->session->{CurrentTheme};
if ($theme ne $oldTheme) {
# $c->app->renderer->paths([$c->app->home->rel_file('themes/default/templates')]);
# $c->app->static->paths([$c->app->home->rel_file('themes/default/public')]);
# if ( $theme ne 'default' ) {
@@ -31,7 +30,7 @@ sub main {
system("/sbin/e-smith/signal-event smanager-theme-change") == 0
or warn "$c->l('ERROR_UPDATING')";
} ## end if ($theme ne $oldTheme)
## (not sure) $c->flash( warning => $c->l('swt_LOGIN_AGAIN') );
## (not sure) $c->flash( warning => $c->l('swt_LOGIN_AGAIN') );
$from = '/initial' if $from eq '/';
$from = '/' . $from if ($from !~ m|^\/|);
$c->redirect_to($from);

View File

@@ -14,29 +14,21 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session
is_normal_password email_simple);
#use esmith::FormMagick qw( validate_password );
#use CGI::FormMagick::Validator qw( call_fm_validation );
use esmith::AccountsDB;
use esmith::ConfigDB;
validate_password email_simple);
use esmith::AccountsDB::UTF8;
use esmith::ConfigDB::UTF8;
use esmith::util;
#use esmith::FormMagick;
#use esmith::cgi;
#use File::Basename;
#use Exporter;
#use Carp qw(verbose);
#use esmith::FormMagick::Panel::useraccounts;
#our $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
#our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
my ($cdb,$adb);
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my $notif = '';
my %usr_datas = ();
my $title = $c->l('usr_FORM_TITLE');
@@ -55,8 +47,8 @@ sub do_display {
my %usr_datas = ();
my $title = $c->l('usr_FORM_TITLE');
my ($notif, $modul) = '';
$cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
$usr_datas{'trt'} = $trt;
if ($trt eq 'ADD') {
@@ -143,8 +135,8 @@ sub do_update {
$usr_datas{trt} = $trt;
my $title = $c->l('usr_FORM_TITLE');
my ($res, $result) = '';
$cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
$adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
if ($trt eq 'ADD') {
@@ -363,10 +355,10 @@ sub lock_account {
$user = $1;
if (system("/sbin/e-smith/signal-event", "user-lock", $user)) {
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return $c->l("usr_ERR_OCCURRED_LOCKING");
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return 'OK';
} else {
return $c->l('NO_SUCH_USER', $user);
@@ -387,10 +379,10 @@ sub remove_account {
$user = $1;
if (system("/sbin/e-smith/signal-event", "user-delete", $user)) {
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return $c->l("ERR_OCCURRED_DELETING");
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
$adb->get($user)->delete;
return 'OK';
} else {
@@ -406,7 +398,7 @@ sub reset_password {
return $c->l('usr_TAINTED_USER');
}
$user = $1;
my $adb = esmith::AccountsDB->open || die "Couldn't open accounts db";
my $adb = esmith::AccountsDB::UTF8->open || die "Couldn't open accounts db";
my $acct = $adb->get($user);
if ($acct->prop('type') eq "user") {
@@ -415,10 +407,10 @@ sub reset_password {
undef $adb;
if (system("/sbin/e-smith/signal-event", "password-modify", $user)) {
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return $c->l("usr_ERR_OCCURRED_MODIFYING_PASSWORD");
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return 'OK';
} else {
return $c->l('NO_SUCH_USER', $user);
@@ -434,31 +426,6 @@ sub check_password {
return validate_password($c, $check_type, $pass1);
} ## end sub check_password
sub validate_password {
my ($c, $strength, $pass) = @_;
use Crypt::Cracklib;
my $reason;
if ($strength eq "none") {
return $c->l("Passwords must be at least 7 characters long") unless (length($pass) > 6);
return "OK";
}
$reason = is_normal_password($c, $pass, undef);
return $reason unless ($reason eq "OK");
return "OK" unless ($strength eq "strong");
if (-f '/usr/lib64/cracklib_dict.pwd') {
$reason = fascist_check($pass, '/usr/lib64/cracklib_dict');
} else {
$reason = fascist_check($pass, '/usr/lib/cracklib_dict');
}
$reason ||= "Software error: password check failed";
return "OK" if ($reason eq "ok");
return $c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because") . " "
. $c->l($reason) . ".";
} ## end sub validate_password
sub emailForward_list {
my $c = shift;
return [
@@ -696,10 +663,10 @@ sub modify_user {
undef $adb;
unless (system("/sbin/e-smith/signal-event", "user-modify", $acctName) == 0) {
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return $c->l('usr_CANNOT_MODIFY_USER');
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
} ## end if ($acctType eq "user")
return 'OK';
} ## end sub modify_user
@@ -732,10 +699,10 @@ sub create_user {
$acctName = $1;
if (system("/sbin/e-smith/signal-event", "user-create", $acctName)) {
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return $c->l("usr_ERR_OCCURRED_CREATING");
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
$c->set_groups();
return 'OK';
} ## end sub create_user
@@ -760,7 +727,7 @@ sub modify_admin {
$acct->merge_props(%newProperties);
undef $adb;
my $status = system("/sbin/e-smith/signal-event", "user-modify-admin", 'admin');
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
if ($status == 0) {
return 'OK';
@@ -784,8 +751,7 @@ sub system_validate_password {
sub system_check_password {
my $c = shift;
my $pass1 = shift;
use esmith::ConfigDB;
my $conf = esmith::ConfigDB->open();
my $conf = esmith::ConfigDB::UTF8->open();
my ($check_type, $rec);
if ($conf) {

View File

@@ -12,12 +12,11 @@ use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use esmith::util;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw( theme_list init_session is_normal_password );
#our $cdb = esmith::ConfigDB->open_ro || die "Couldn't open configuration db";
use SrvMngr qw( theme_list init_session validate_password );
sub main {
my $c = shift;
@@ -161,7 +160,7 @@ sub reset_password {
my $ret;
return $c->l('usr_TAINTED_USER') unless (($user) = ($user =~ /^(\w[\-\w_\.]*)$/));
$user = $1;
my $adb = esmith::AccountsDB->open();
my $adb = esmith::AccountsDB::UTF8->open();
my $acct = $adb->get($user);
return $c->l('NO_SUCH_USER', $user) unless ($acct->prop('type') eq 'user');
$ret = esmith::util::setUserPasswordRequirePrevious($user, $oldpassword, $password) if $trt ne 'RESET';
@@ -171,10 +170,10 @@ sub reset_password {
undef $adb;
if (system("/sbin/e-smith/signal-event", "password-modify", $user)) {
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return $c->l("usr_ERR_OCCURRED_MODIFYING_PASSWORD");
}
$adb = esmith::AccountsDB->open();
$adb = esmith::AccountsDB::UTF8->open();
return 'OK';
} ## end sub reset_password
@@ -194,34 +193,10 @@ sub check_password {
my $c = shift;
my $password = shift;
my $strength;
my $cdb = esmith::ConfigDB->open_ro || die "Couldn't open configuration db";
my $cdb = esmith::ConfigDB::UTF8->open_ro || die "Couldn't open configuration db";
my $rec = $cdb->get('passwordstrength');
$strength = ($rec ? ($rec->prop('Users') || 'none') : 'none');
return validate_password($c, $strength, $password);
} ## end sub check_password
sub validate_password {
my ($c, $strength, $pass) = @_;
use Crypt::Cracklib;
if ($strength eq "none") {
return $c->l("Passwords must be at least 7 characters long") unless (length($pass) > 6);
return "OK";
}
my $reason = is_normal_password($c, $pass, undef);
return $reason unless ($reason eq "OK");
return "OK" unless ($strength eq "strong");
if (-f '/usr/lib64/cracklib_dict.pwd') {
$reason = fascist_check($pass, '/usr/lib64/cracklib_dict');
} else {
$reason = fascist_check($pass, '/usr/lib/cracklib_dict');
}
$reason ||= "Software error: password check failed";
return "OK" if ($reason eq "ok");
return
$c->l("Bad Password Choice") . ": "
. $c->l("The password you have chosen is not a good choice, because") . " "
. $c->($reason) . ".";
} ## end sub validate_password
1;

View File

@@ -15,14 +15,15 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
use esmith::ConfigDB;
use File::Basename;
use HTML::Entities;
use SrvMngr qw(gen_locale_date_string);
use File::Temp qw(tempfile);
use constant TRUE => 1;
use constant FALSE => 0;
our $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
use esmith::ConfigDB::UTF8;
our $cdb;
our @logfiles = (); # with array
sub main {
@@ -31,7 +32,9 @@ sub main {
my %log_datas = ();
my $title = $c->l('log_FORM_TITLE');
my $notif = '';
$log_datas{default_op} = ($cdb->get('viewlogfiles')->prop('DefaultOperation')) || 'view';
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $viewlog = $cdb->get('viewlogfiles');
$log_datas{default_op} = ($viewlog ? $viewlog->prop('DefaultOperation') : undef) || 'view';
$c->stash(title => $title, notif => $notif, log_datas => \%log_datas);
$c->render(template => 'viewlogfiles');
} ## end sub main
@@ -230,6 +233,7 @@ sub showlogFile {
sub download_logFile {
my ($c, %log_datas) = @_;
my $fullpath = "/var/log/$log_datas{filename}";
$cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
# Save this information for later.
$cdb->get('viewlogfiles')->merge_props('DefaultOperation', $log_datas{operation});

View File

@@ -13,11 +13,13 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session);
our $db = esmith::ConfigDB->open || die "Couldn't open config db";
use esmith::ConfigDB::UTF8;
our $db ;
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$db = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %wkg_datas = ();
my $title = $c->l('wkg_FORM_TITLE');
my $modul = '';

View File

@@ -3,7 +3,7 @@ package SrvMngr::Controller::Yum;
#----------------------------------------------------------------------
# heading : System
# description : Software installer
# navigation : 4000 300
# navigation : 4000 500
#
# routes : end
#----------------------------------------------------------------------
@@ -13,28 +13,30 @@ use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number_or_blank);
use esmith::ConfigDB;
# dnf_* should remain ASCII; yum_repositories do not need to be UTF-8
use esmith::ConfigDB::UTF8;
use esmith::util;
use File::Basename;
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
our $cdb;
my $dnf_status_file = '/var/cache/dnf/dnf.status';
#use File::stat;
our %dbs;
for (qw(available installed updates)) {
$dbs{$_} = esmith::ConfigDB->open_ro("dnf_$_")
$dbs{$_} = esmith::ConfigDB::UTF8->open_ro("dnf_$_")
or die "Couldn't open dnf_$_ DB\n";
}
for (qw(repositories)) {
$dbs{$_} = esmith::ConfigDB->open("yum_$_")
$dbs{$_} = esmith::ConfigDB::UTF8->open("yum_$_")
or die "Couldn't open yum_$_ DB\n";
}
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %yum_datas = ();
my $title = $c->l('yum_FORM_TITLE');
my $dest = 'yum';
@@ -60,6 +62,7 @@ sub do_display {
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'STAT');
$cdb = esmith::ConfigDB::UTF8->open || die "Couldn't open config db";
my %yum_datas = ();
my $title = $c->l('yum_FORM_TITLE');
my ($notif, $dest) = '';

View File

@@ -2,7 +2,7 @@
'clm_LABEL_FILESYSTEM_SCAN_PERIOD' => 'Scan filesystem',
'clm_DESC_FILESYSTEM_SCAN_PERIOD' => '<h2>General Settings</h2>
If this option is enabled then the filesystem will be
scanned for viruses.A report of any found viruses will be
scanned for viruses. A report of any found viruses will be
emailed to the administrator.',
'clm_LABEL_QUARANTINE' => 'Quarantine infected files',
'clm_LABEL_CLAM_VERSIONS' => 'ClamAV and db versions',

View File

@@ -1,5 +1,5 @@
'dat_FORM_TITLE' => 'Date and time configuration',
'dat_The_time_is_currently' => 'The time is currently:',
'dat_INITIAL_DESC' => 'This is where you configure the date and time of this server. You may use an existing network time server or
manually set the date and time for your time zone.',
'dat_SET_DATE_TITLE' => 'Set Date and Time',
@@ -18,7 +18,7 @@ manually set the date and time for your time zone.',
'dat_DECEMBER' => 'December',
'dat_NEW_M/D/Y' => 'New month/day/year:',
'dat_NEW_H/M/S' => 'New hour/min/sec:',
'dat_AM/PM_AND_TZ' => 'AM/PM and time zone:',
'dat_TZ' => 'Time zone:',
'dat_NTP_ENABLE_DESC' => 'The server can periodically synchronize the system clock to a network time protocol (NTP) server. If you select this option, enter the hostname or IP address of the NTP server below.',
'dat_NTP_CONFIGURE_DESC' => 'The server is periodically synchronizing the system clock to the network time protocol (NTP) server specified below. To synchronize to a different NTP server, enter a different hostname or IP address in the field below.',
'dat_NTP_DISABLE_DESC' => 'Choose this option to stop syncronizing the system clock to the NTP
@@ -38,9 +38,7 @@ server.When the NTP service is disabled, you can set the system date and time ma
'dat_INVALID_SECOND' => 'Error: invalid second',
'dat_MONTH_BETWEEN_1_AND_12' => 'Please choose a month value between 1 and 12.',
'dat_INVALID_MONTH' => 'Error: invalid month',
'dat_UPDATING_CLOCK' => 'System clock is being updated. Please wait for a few seconds,
then click <A HREF="datetime?page=1&wherenext=Verify" TARGET="main">here</A>
to verify changes.',
'dat_UPDATING_CLOCK' => 'System clock is being updated',
'dat_ERR_SETTING_CLOCK' => 'Error occurred while setting system time and hardware clock.',
'dat_SERVER_DISABLED' => 'Network time server disabled successfully',
'dat_SERVER_DISABLED_DESC' => 'You have disabled this service: The server will rely on its internal
@@ -57,3 +55,8 @@ clock, and <b>will not</b> try to synchronize from a time server.',
'dat_NTP_DISABLE_TITLE' => 'Disable Network Time Server',
'dat_CURRENT_SETTING' => 'Current setting',
'Date and time' => 'Date and time',
'dat_ntp_server' => 'NTP server',
'dat_manually_set' => 'Set manually',
'dat_NTP_Server_URL' =>'NTP Server URL:',
'dat_set_manually' =>'Set Date and Time:',
'dat_Invalid_date' => 'Invalid date',

View File

@@ -14,26 +14,26 @@ web site for that domain.',
i-bay as the content.',
'dom_DOMAIN_NAME_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain name
[_1].The domain name should contain one or more
letters, numbers, periods and minus signs.Did not create new domain.',
letters, numbers, periods and minus signs. Did not create new domain.',
'dom_DOMAIN_DESCRIPTION_VALIDATION_ERROR' => 'Error: unexpected or missing characters in domain description
[_1]. Did not create new domain.',
'dom_DOMAIN_IN_USE_ERROR' => 'Error: domain [_1] is already in use.Did not create
'dom_DOMAIN_IN_USE_ERROR' => 'Error: domain [_1] is already in use. Did not create
new domain.',
'dom_SYSTEM_DOMAIN_ERROR' => 'Error: domain [_1] is your system domain name.You
cannot have a domain with the same name.Did not create new domain.',
'dom_SYSTEM_DOMAIN_ERROR' => 'Error: domain [_1] is your system domain name. You
cannot have a domain with the same name. Did not create new domain.',
'dom_SUCCESSFULLY_CREATED' => 'Successfully created domain [_1].Your web
server is now being restarted.The links on this page will be
server is now being restarted. The links on this page will be
inactive until the web server restart is complete.',
'dom_MODIFY_TITLE' => 'Modify domain',
'dom_NONEXISTENT_DOMAIN_ERROR' => 'Error: [_1] is not an existing domain.',
'dom_SUCCESSFULLY_MODIFIED' => 'Successfully modified domain [_1].Your web
server is now being restarted.The links on this page will be inactive until the web server restart is complete.',
server is now being restarted. The links on this page will be inactive until the web server restart is complete.',
'dom_REMOVE_TITLE' => 'Remove domain',
'dom_REMOVE_DESCRIPTION' => 'You are about to remove the domain "[_1]" ([_2]).',
'dom_ABOUT_TO_REMOVE' => 'Are you sure you wish to remove this domain ?',
'dom_ERROR_WHILE_REMOVING_DOMAIN' => 'Error: internal failure while removing domain [_1].',
'dom_SUCCESSFULLY_DELETED' => 'Successfully deleted domain [_1]. Your web server
is now being restarted.The links on this page will be inactive
is now being restarted. The links on this page will be inactive
until the web server restart is complete.',
'dom_DESC_CORPORATE_DNS_CURRENT' => 'Corporate DNS Settings',
'dom_DOMAINS_PAGE_CORPORATE_DNS' => 'Modify corporate DNS settings',

View File

@@ -128,7 +128,7 @@
'FM_IP_NUMBER3' => '[_1] is more than 255',
'FM_USERNAME' => 'This field must look like a valid username (3 to 8 letters and numbers)',
'FM_PASSWORD1' => 'You must provide a password.',
'FM_PASSWORD2' => 'The password you provided was not a good password.A good password must contain all of the following: upper case letter, lower case letter, number, non-alphanumeric character, be at least 7 characters long.',
'FM_PASSWORD2' => 'The password you provided was not a good password. A good password must contain all of the following: upper case letter, lower case letter, number, non-alphanumeric character, be at least 7 characters long.',
'FM_MAC_ADDRESS1' => 'You must provide a MAC address.',
'FM_MAC_ADDRESS2' => 'The MAC address you provided was not valid.',
'FM_ERR_UNEXPECTED_DESC' => 'Error: unexpected or missing characters in description',
@@ -151,4 +151,5 @@ SMALL => 'Small',
MEDIUM => 'Medium',
LARGE => 'Large',
FIELD_INVALID_CHARS => 'A field you entered contains invalid characters.',
'REPORT_GENERATED' => "Report generated",
'END_OF_REPORT' => 'End of Report',

View File

@@ -4,7 +4,7 @@
'grp_ACCOUNT_CONFLICT' => 'Error: the group "[_1]" can\'t be created because there is
already a [_2] account of that name.',
'grp_INVALID_GROUP_DESCRIPTION' => 'Error: unexpected or missing characters in group description',
'grp_NO_MEMBERS' => 'Error: no members in group.Did not create new group.',
'grp_NO_MEMBERS' => 'Error: no members in group. Did not create new group.',
'grp_CREATED_GROUP' => 'Successfully created user group',
'grp_DELETED_GROUP' => 'Successfully removed user group',
'grp_MODIFIED_GROUP' => 'Successfully modifed user group',

View File

@@ -34,17 +34,17 @@ the local network. Please enter a valid IP address in the
format "aaa.bbb.ccc.ddd".',
'hos_ETHERNET_ADDRESS_DESCRIPTION' => 'The ethernet address is optional and causes the DHCP server to
statically bind the local IP address to the computer with this
ethernet address.If specified, it must be of the form
ethernet address. If specified, it must be of the form
"AA:BB:CC:DD:EE:FF" and must contain only the numbers 0-9 and
the letters A-F.',
'hos_CREATE_LOCAL_HOST_TITLE' => 'Create a new hostname referring to a local host.',
'hos_DIDNT_ENTER_LOCAL_IP' => 'Error: You did not specify a Local IP address.IP
'hos_DIDNT_ENTER_LOCAL_IP' => 'Error: You did not specify a Local IP address. IP
addresses must contain only numbers and periods and
be in the form "aaa.bbb.ccc.ddd".Did not create hostname.',
'hos_IP_VALIDATION_ERROR' => 'Error: IP Address [_1] is
invalid. IP Addresses must contain only numbers and periodsand be in the form "aaa.bbb.ccc.ddd". Did not create hostname.',
'hos_MAC_ADDRESS_VALIDATION_ERROR' => 'Error: Ethernet address [_1]
is invalid.Ethernet addresses must be in the
is invalid. Ethernet addresses must be in the
form "AA:BB:CC:DD:EE:FF" and only contain the
numbers 0-9 and the letters A-F. Did not create
hostname.',

View File

@@ -1,72 +0,0 @@
package SrvMngr::I18N::Modules::Letsencrypt::en;
use strict;
use warnings;
use utf8;
use Mojo::Base 'SrvMngr::I18N';
use SrvMngr::I18N::Modules::General::en;
my %lexicon = (
#
# Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
#
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings',
'lets_HOOKSCRIPT_STATUS' => 'Hookscript Status',
'lets_SERVICE_STATUS' => 'Service Status',
'lets_EMAIL' => 'Email',
'lets_Back' => 'Back',
'lets_Internal_IP' => 'Internal IP',
'lets_Save' => 'Save',
'lets_Issuer' => 'Issuer',
'lets_IS_IN_CERT' => 'Is In cart',
'lets_For_this_Server' => 'For this Server',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain which is enabled',
'lets_Check_just_one_domain' => 'Check just one domain',
'lets_PARAMS_panel_action_was_successful' => 'PARAMS panel action was successful',
'lets_Check_all_domains' => 'Check all domains',
'lets_LIST_panel_action_was_successful' => 'LIST panel action was successful',
'lets_Status_Report' => 'Status Report',
'lets_LABEL_NAMESERVERS' => 'Label timeservers',
'lets_Loop_through_and_check_the' => 'Loop through and check the letsencrypt status for a specific domain',
'lets_Letsencrypt_certificate' => 'Letsencrypt certificate',
'lets_Error_Status_Report' => 'Error Status Report',
'lets_Not_Before' => 'Not Before',
'lets_Content' => 'Content',
'lets_CONFIG_LETSENCRYPT' => 'confirm Letsencrypt',
'lets_API_STATUS' => 'ape Status',
'lets_ACCEPT_TERMS_STATUS' => 'Accept Terms Status',
'lets_Check_all_enabled_domains' => 'Check all enabled domains',
'lets_All_domains_check_result' => 'All domains check result',
'lets_CHECKALLDOMAINS_panel_action_was_successful' => 'CHECKALLDOMAINS panel action was successful',
'lets_Domains_name' => 'Domains name',
'lets_HOSTOVERRIDE_STATUS' => 'Hostoverride Status',
'lets_List_of_Domains_and_Hosts' => 'List of Domains and Hosts',
'lets_Brief_description' => 'Brief description',
'lets_KEYSIZE_STATUS' => 'Keysize Status',
'lets_Domain_name_/_HOSTNAME' => 'Domain name / HOSTNAME',
'lets_Enabled_domains_check_result' => 'Enabled domains check result',
'lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful' => 'CHECKALLENABLEDDOMAINS panel action was successful',
'lets_Internet_IP' => 'Internet IP',
'lets_Expiry' => 'Expiry',
'lets_CHECK_ALL_DOMAINS' => 'Check All Domains',
'lets_LABEL_POINT' => 'Label Point',
'lets_CHECK' => 'Check',
'lets_CONFIG' => 'Config',
'lets_Current_certificate_details' => 'Current certificate details',
'lets_LABEL_LECERT' => 'Label secret',
'lets_One_domain_check_result' => 'One domain check result',
'lets_CHECKONEDOMAIN_panel_action_was_successful' => 'CHECKONEDOMAIN panel action was successful',
'lets_CONFIGUREMODE_STATUS' => 'Configuremode Status',
'lets_CHECK_ALL_ENABLED_DOMAINS' => 'Check All Enabled Domains',
'lets_External_Interface_IP' => 'External Interface IP',
'lets_APPLY' => 'Apply',
);
our %Lexicon = (
%{ SrvMngr::I18N::Modules::General::en::Lexicon },
%lexicon
);
1;

View File

@@ -1,55 +0,0 @@
#
# Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
# edited by bjr 09Jan2025
#
'lets_Manage_letsencrypt-config_settings:' => 'Manage letsencrypt-config settings',
'lets_HOOKSCRIPT_STATUS' => 'Hookscript Status',
'lets_SERVICE_STATUS' => 'Service Status',
'lets_EMAIL' => 'Email',
'lets_Back' => 'Back',
'lets_Internal_IP' => 'Internal IP',
'lets_Save' => 'Save',
'lets_Issuer' => 'Issuer',
'lets_IS_IN_CERT' => 'Is in certificate',
'lets_For_this_Server' => 'For this Server',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain',
'lets_Loop_through_checking_the_letsencrypt' => 'Loop through checking the letsencrypt status for each configured domain which is enabled',
'lets_Check_just_one_domain' => 'Check just one domain',
'lets_PARAMS_panel_action_was_successful' => 'Parameter panel action was successful',
'lets_Check_all_domains' => 'Check all domains',
'lets_LIST_panel_action_was_successful' => 'List panel action was successful',
'lets_Status_Report' => 'Status Report',
'lets_LABEL_NAMESERVERS' => 'Label timeservers',
'lets_Loop_through_and_check_the' => 'Loop through and check the letsencrypt status for a specific domain',
'lets_Letsencrypt_certificate' => 'Letsencrypt certificate',
'lets_Error_Status_Report' => 'Error Status Report',
'lets_Not_Before' => 'Not Before',
'lets_Content' => 'Content',
'lets_CONFIG_LETSENCRYPT' => 'Configure Letsencrypt',
'lets_API_STATUS' => 'API Status',
'lets_ACCEPT_TERMS_STATUS' => 'Accept Terms Status',
'lets_Check_all_enabled_domains' => 'Check all enabled domains',
'lets_All_domains_check_result' => 'All domains check result',
'lets_CHECKALLDOMAINS_panel_action_was_successful' => 'Check all domains panel action was successful',
'lets_Domains_name' => 'Domains name',
'lets_HOSTOVERRIDE_STATUS' => 'Hostoverride Status',
'lets_List_of_Domains_and_Hosts' => 'List of Domains and Hosts',
'lets_Brief_description' => 'Brief description',
'lets_KEYSIZE_STATUS' => 'Keysize Status',
'lets_Domain_name_/_HOSTNAME' => 'Domain name / HOSTNAME',
'lets_Enabled_domains_check_result' => 'Enabled domains check result',
'lets_CHECKALLENABLEDDOMAINS_panel_action_was_successful' => 'Check all enabled domains panel action was successful',
'lets_Internet_IP' => 'Internet IP',
'lets_Expiry' => 'Expiry',
'lets_CHECK_ALL_DOMAINS' => 'Check All Domains',
'lets_LABEL_POINT' => 'Label Point',
'lets_CHECK' => 'Check',
'lets_CONFIG' => 'Config',
'lets_Current_certificate_details' => 'Current certificate details',
'lets_LABEL_LECERT' => 'Label secret',
'lets_One_domain_check_result' => 'One domain check result',
'lets_CHECKONEDOMAIN_panel_action_was_successful' => 'Check one domain panel action was successful',
'lets_CONFIGUREMODE_STATUS' => 'Configure mode Status',
'lets_CHECK_ALL_ENABLED_DOMAINS' => 'Check All Enabled Domains',
'lets_External_Interface_IP' => 'External Interface IP',
'lets_APPLY' => 'Apply',

View File

@@ -12,13 +12,13 @@
'ln_REMOVE_CONFIRM' => 'Are you sure you wish to remove this network?',
'ln_DEFAULT' => 'default',
'ln_NUMBER_OF_HOSTS' => 'Number of hosts',
'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK' => 'Error: router address {$networkRouter} is not accessible from local network. Did not add network.',
'ln_NOT_ACCESSIBLE_FROM_LOCAL_NETWORK' => 'Error: router address [_3] is not accessible from local network. Did not add network.',
'ln_LOCALNETWORK_ADD'=>'Add network',
'ln_NETWORK_ALREADY_LOCAL' => ' Error: network {$network} (derived from network {$networkAddress} and subnet mask {$networkMask}) is already considered local. Did not add new network. ',
'ln_NETWORK_ALREADY_ADDED' => 'Error: network {$network} (derived from network {$networkAddress} and subnet mask {$networkMask}) has already been added. Did not add new network.',
'ln_NETWORK_ALREADY_LOCAL' => ' Error: network [_1] (derived from network [_1] and subnet mask [_2]) is already considered local. Did not add new network. ',
'ln_NETWORK_ALREADY_ADDED' => 'Error: network [_1] (derived from network [_1] and subnet mask [_2]) has already been added. Did not add new network.',
'ln_ERROR_CREATING_NETWORK' => 'Error occurred while creating network.',
'ln_SUCCESS' =>'Successfully added network [_1]/[_2] via router [_3].',
'ln_SUCCESS_SINGLE_ADDRESS' =>'Successfully added network {$network}/{$networkMask} via router {$networkRouter}. Your server will grant local access privileges to the single IP address {$network}. ',
'ln_SUCCESS_SINGLE_ADDRESS' =>'Successfully added network [_1]/[_2] via router [_3]. Your server will grant local access privileges to the single IP address [_1]. ',
'ln_SUCCESS_NETWORK_RANGE' =>'Successfully added network [_1]/[_2] via router [_3]. Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6]. ',
'ln_NO_SUCH_NETWORK' =>'Network not found in network db',
'ln_SUCCESS_REMOVED_NETWORK' =>'Successfully removed network [_1]/[_2] via router [_3].',
@@ -26,5 +26,5 @@
'ln_NO_ADDITIONAL_NETWORKS' => 'No additional networks',
'ln_REMOVE_HOSTS_DESC' => 'Local hosts configured on the network you are about to remove have been detected. By default, they will also be removed. Uncheck this box if, for some reason, you do not wish this to happen. Note that they will not be treated as local, and may not even be reachable, after this network is removed. ',
'ln_REMOVE_HOSTS_LABEL' => 'Remove hosts on network',
'ln_extra' => '{$network}/{$networkMask} via router $networkRouter}.',
'ln_SUCCESS_NONSTANDARD_RANGE' =>'<p>Successfully added network [_1]/[_2] via router [_3].</p><p> Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6].</p><p> Warning: the ProFTPd FTP server cannot handle this nonstandard subnet mask. The simpler specification <b>[_7]</b> will be used instead.</p>',
'ln_extra' => '[_1]/[_2] via router $networkRouter}.',
'ln_SUCCESS_NONSTANDARD_RANGE' =>'<p>Successfully added network [_1]/[_2] via router [_3].</p><p> Your server will grant local access privileges to [_4] IP addresses in the range [_5] to [_6].</p><p> Warning: the ProFTPd FTP server cannot handle this nonstandard subnet mask. The simpler specification <b>[_7]</b> will be used instead.</p>',

View File

@@ -1,16 +1,13 @@
'pf_FORM_TITLE' => 'Configure Port Forwarding',
'pf_FIRST_PAGE_DESCRIPTION' => '<p>
You can use this panel to modify your firewall rules so
'pf_FIRST_PAGE_DESCRIPTION' => 'You can use this panel to modify your firewall rules so
as to open a specific port on this server and forward it
to another port on another host. Doing so will permit
incoming traffic to directly access a private host on
your LAN.
</p><p>
WARNING: Misuse of this feature can seriously compromise the
security of your network. Do not use this feature
lightly, or without fully understanding the implications
of your actions.
</p>',
of your actions.',
'pf_CREATE_RULE' => 'Create portforwarding rule',
'pf_SUMMARY_ADD_DESC' => 'The following summarizes the port-forwarding rule
that you are about to add. If you are satisfied with the rule,
@@ -22,13 +19,13 @@
port-forwarding rules installed on this server. Click on the
\'Remove\' link to remove the corresponding rule.',
'pf_NO_FORWARDS' => 'There are currently no forwarded ports on the system.',
'pf_CREATE_PAGE_DESCRIPTION' => '<p>Select the protocol, the port you wish to forward, the
'pf_CREATE_PAGE_DESCRIPTION' => 'Select the protocol, the port you wish to forward, the
destination host, and the port on the destination host
that you wish to forward to. If you wish to specify a port
range, enter the lower and upper boundaries separated by a
hyphen. The destination port may be left blank, which will
instruct the firewall to leave the source port
unaltered.</p>',
unaltered',
'pf_LABEL_SOURCE_PORT' => 'Source Port(s)',
'pf_LABEL_PROTOCOL' => 'Protocol',
'pf_LABEL_DESTINATION_PORT' => 'Destination Port(s)',
@@ -53,4 +50,4 @@
'pf_ERR_BADAHOST' => 'This does not appear to be a valid IP address list.
ie: 192.168.0.1,192.168.1.1/24',
'pf_IN_SERVERONLY' => 'This server is currently in serveronly mode and portforwarding
is possible only to localhost.',
is possible only to localhost.',

View File

@@ -14,7 +14,7 @@ For example, you may wish to create a pseudonym
"webmaster" for your "webdevelopers" group or a
pseudonym "joe" for the user "joseph".</p>
<p>The server automatically creates pseudonyms of the form
firstname.lastname and firstname_lastname for every user
firstname. lastname and firstname_lastname for every user
on the system and a pseudonym "everyone" which contains
all users on the system.</p>
<p>Pseudonyms also allow you to create e-mail aliases for valid

View File

@@ -8,6 +8,15 @@ reports are available.</P>
these reports</P>',
'qma_REPORT_TYPE' => 'Choose a report type',
'qma_GENERATE_REPORT' => 'Generate report',
'qma_INVALID_REPORT_TYPE' => 'Invalid report type: ',
'qma_REPORT_GENERATED' => 'Report generated: ',
'qma_END_OF_REPORT' => 'End of Report',
'Mail log file analysis' => 'Mail log file analysis',
'qma_Daily_Summary_Report_yesterday' => 'Summary report for yesterday',
'qma_Daily_Summary_Report_today' => 'Summary report for today up to now',
'qma_Daily_Summary_Report_all' => 'Summary report for all time up to now',
'qma_LIST_OUTGOING' => 'List outgoing messages and recipients',
'qma_SUMMARIZE_QUEUE' => 'Summarize status of mail queue',
'qma_SUCCESSFUL_DELIVERY_DELAY' => 'Successful delivery delay distribution',
@@ -20,9 +29,4 @@ these reports</P>',
'qma_SENDER_STATS' => 'Sender statistics',
'qma_SENDMAIL_STYLE' => 'Sendmail style log',
'qma_REASONS_SUCCESS' => 'Reasons for success',
'qma_SENDER_UIDS' => 'Sender uids',
'qma_INVALID_REPORT_TYPE' => 'Invalid report type: ',
'qma_REPORT_GENERATED' => 'Report generated: ',
'qma_END_OF_REPORT' => 'End of Report',
'Mail log file analysis' => 'Mail log file analysis',
'qma_SENDER_UIDS' => 'Sender uids',

View File

@@ -26,7 +26,9 @@ experienced administrators
for remote problem diagnosis and resolution.
We recommend leaving this
parameter set to "No Access"
unless you have a specific reason to do otherwise.',
unless you have a specific reason to do otherwise.
Note that an "Autoblock" feature is enabled by default when public access is enabled; to disable or tune this feature, refer to the manual at https://wiki.koozali.org/AutoBlock
',
'rma_TITLE_FTP_ACCESS' => 'FTP Settings',
'rma_DESC_FTP_ACCESS' => 'You can also control <b>FTP</b> access to your server. We
recommend leaving this parameter set to \'no access\' unless you
@@ -75,11 +77,11 @@ connected to a server serial port.',
'rma_LABEL_PPTP_ACCESS' => 'PPTP default user access',
'rma_TITLE_TELNET_ACCESS' => 'Telnet Settings',
'rma_DESC_TELNET_ACCESS' => 'WARNING:Telnet is currently enabled, but this feature is
no longer supported.Telnet is inherently insecure and should only
no longer supported. Telnet is inherently insecure and should only
be used in circumstances where no practical alternative exists. You
should change option to [_1] and use
secure shell if remote access is
required.Once disabled, telnet will no longer appear on this
required. Once disabled, telnet will no longer appear on this
screen. ',
'rma_TITLE_IPSECRW' => 'IPSEC Client (Roadwarrior) Settings',
'rma_DESC_IPSECRW' => 'You can allow IPSEC client access to your server, authenticated by
@@ -90,4 +92,4 @@ to the number 0 unless you require IPSEC client access.',
can do so here.<br>Any old certificates will no longer
authenticate against the server, so <b><i>all IPSEC clients will
need to import a new certificate!</i></b>.',
'rma_LABEL_IPSECRW_RESET' => 'Reset digital certificates',
'rma_LABEL_IPSECRW_RESET' => 'Reset digital certificates',

View File

@@ -2,7 +2,7 @@
'rvw_FORM_TITLE' => 'Review configuration',
'rvw_DESCRIPTION' => 'This report summarizes the networking, server, and domain
parameters on this server relevant to configuring
the client computers on your network.You may wish to print this
the client computers on your network. You may wish to print this
page and use it as a reference.',
'rvw_NETWORKING_PARAMS' => 'Networking Parameters',
'rvw_SERVER_MODE' => 'Server Mode',

View File

@@ -4,7 +4,7 @@
by the services running on your server.',
'log_LOG_FILE_SELECT_DESC' => 'Choose a log file to view',
'log_FILTER_PATTERN_DESC' => 'You may optionally specify a filter pattern to display only the
lines from the log file which match this pattern.If you leave
lines from the log file which match this pattern. If you leave
this field blank, all available lines of the log file will be
displayed. Note that this option is not used if you download the
logfile.',

View File

@@ -4,19 +4,19 @@ use strict;
use warnings;
use utf8;
use esmith::ConfigDB;
use esmith::AccountsDB;
use esmith::ConfigDB::UTF8;
use esmith::AccountsDB::UTF8;
use esmith::util;
use Net::LDAP qw/LDAP_INVALID_CREDENTIALS/;
our ($cdb,$adb);
sub init_data {
my %datas = ();
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Config DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Config DB");
my $sysconfig = $cdb->get("sysconfig");
$datas{'lang'} = $sysconfig->prop('Language') || 'en_US';
@@ -42,7 +42,7 @@ sub init_data {
sub reconf_needed {
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Config DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Config DB");
#my $unsafe = ($cdb->get('bootstrap-console') and $cdb->get('bootstrap-console')->prop('Run') eq 'yes') ||
# ($cdb->get('UnsavedChanges') and $cdb->get('UnsavedChanges')->value eq 'yes') || '0';
my $unsafe = ($cdb->get('UnsavedChanges') and $cdb->get('UnsavedChanges')->value eq 'yes') || '0';
@@ -55,7 +55,7 @@ sub check_credentials {
my ($c, $username, $password) = @_;
return unless $username || $password;
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Configuration DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Configuration DB");
my $l = $cdb->get('ldap');
my $status = $l->prop('status') || "disabled";
unless ($status eq "enabled" ) {
@@ -88,13 +88,13 @@ sub check_adminalias {
my $c = shift;
my $alias;
my $cdb = esmith::ConfigDB->open_ro() or die("can't open Configuration DB");
$cdb = esmith::ConfigDB::UTF8->open_ro() or die("can't open Configuration DB");
if (defined $cdb->get('AdminAlias')) {
$alias = $cdb->get('AdminAlias')->value;
}
return undef unless $alias;
my $adb = esmith::AccountsDB->open_ro() or die("can't open Accounts DB");
$adb = esmith::AccountsDB::UTF8->open_ro() or die("can't open Accounts DB");
my $arec = $adb->get( $alias );
return undef unless $arec;
@@ -105,4 +105,4 @@ sub check_adminalias {
}
1;
1;

View File

@@ -0,0 +1,100 @@
# Optimized SrvMngr_Auth module using stash caching and Exporter
package SrvMngr_Auth;
use strict;
use warnings;
use Exporter qw(import); # Import the Exporter module
use esmith::AccountsDB::UTF8;
# Define functions to be exported upon request
our @EXPORT_OK = qw(check_admin_access load_user_auth_info has_panel_access get_panel_from_path);
# Helper function to extract panel name from path
sub get_panel_from_path {
my ($path) = @_;
if ($path =~ m{^/([^/]+)}) {
return $1;
}
return ''; # Return empty string if no panel found
}
# Load user authentication info and cache it in the stash
sub load_user_auth_info {
my ($c) = @_;
# Check if auth info is already cached in the stash
return if exists $c->stash->{auth_info};
my %auth_info = (
username => '', # Initialize username
is_admin => 0,
allowed_panels => [],
);
# Get username from session
$auth_info{username} = $c->session->{username} || ''; # Provide default empty string
# Check if user is admin
$auth_info{is_admin} = $c->is_admin || 0;
# If not admin, get allowed panels
if (!$auth_info{is_admin} && $auth_info{username}) {
my $accountsdb = esmith::AccountsDB::UTF8->open_ro();
if ($accountsdb) {
my $user_rec = $accountsdb->get($auth_info{username});
# Check if the property exists before trying to get its value
if (defined $user_rec && $user_rec->prop('AdminPanels')) {
# Get comma-separated list of allowed admin panels
my $admin_panels = $user_rec->prop('AdminPanels');
$auth_info{allowed_panels} = [split(/,/, $admin_panels)];
}
}
}
# Store the calculated info in the stash
$c->stash(auth_info => \%auth_info);
}
# Check if a user has access to a specific panel (uses cached info)
sub has_panel_access {
my ($c, $panel) = @_;
# Ensure auth info is loaded
load_user_auth_info($c);
my $auth_info = $c->stash->{auth_info};
# Check if requested panel is in allowed panels
foreach my $allowed_panel (@{$auth_info->{allowed_panels}}) {
return 1 if lc($panel) eq lc($allowed_panel)
|| lc(substr($panel, 0, length($allowed_panel))) eq lc($allowed_panel);
}
return 0;
}
# Main function to check admin access (uses cached info)
sub check_admin_access {
my ($c) = @_;
# Ensure auth info is loaded
load_user_auth_info($c);
my $auth_info = $c->stash->{auth_info};
# First check if user is admin
return 1 if $auth_info->{is_admin};
# If not admin, check if they have access to the specific panel
my $current_path = $c->req->url->path;
my $requested_panel = $current_path;
return 0 unless $requested_panel;
# Check if user has access to this panel using the cached info
return has_panel_access($c, $requested_panel);
}
1; # Return true value for module loading

View File

@@ -5,11 +5,11 @@
use strict;
use warnings;
use esmith::ConfigDB;
use esmith::ConfigDB::UTF8;
use constant WEBFUNCTIONS => '/usr/share/smanager/lib/SrvMngr/Controller/';
my $rtdb = esmith::ConfigDB->open('routes') or
my $rtdb = esmith::ConfigDB::UTF8->open('routes') or
die "Couldn't access Routes database\n";
my @routes = $rtdb->get_all_by_prop( type => 'route' );

View File

@@ -7,7 +7,7 @@
use strict;
use warnings;
use esmith::ConfigDB;
use esmith::ConfigDB::UTF8;
sub gen_pwd {
use MIME::Base64 qw(encode_base64);
@@ -29,7 +29,7 @@ sub gen_pwd {
return $p;
}
my $cdb = esmith::ConfigDB->open() || die "Couldn't open config db";
my $cdb = esmith::ConfigDB::UTF8->open() || die "Couldn't open config db";
my $pwds = $cdb->get_prop('smanager','Secrets');

View File

@@ -14,6 +14,10 @@ BEGIN
$ENV{'HOME'} = '/usr/share/smanager';
delete $ENV{'ENV'};
esmith::util::setRealToEffective();
#to help debug UTF8, see perlrun and perlvar -CSAD or -CLSD
#print '$ENV{PERL_UNICODE}='.$ENV{'PERL_UNICODE'}."\n" if $ENV{'PERL_UNICODE'};
#print '${^UNICODE}='.${^UNICODE}.' ; ${^UTF8LOCALE}='.${^UTF8LOCALE} ."\n";
#print '${^OPEN}'.${^OPEN}."\n" if ${^OPEN} ;
}

View File

@@ -6,8 +6,8 @@ use Test::Mojo;
use FindBin;
use lib "$FindBin::Bin/../lib";
eval "use esmith::ConfigDB";
plan skip_all => 'esmith::ConfigDB (and others) required for testing 002_basic' if $@;
eval "use esmith::ConfigDB::UTF8";
plan skip_all => 'esmith::ConfigDB::UTF8 (and others) required for testing 002_basic' if $@;
plan tests => 3;

View File

@@ -6,8 +6,8 @@ use Test::Mojo;
use FindBin;
use lib "$FindBin::Bin/../lib";
eval "use esmith::ConfigDB";
plan skip_all => 'esmith::ConfigDB (and others) required for testing 004_panels' if $@;
eval "use esmith::ConfigDB::UTF8";
plan skip_all => 'esmith::ConfigDB::UTF8 (and others) required for testing 004_panels' if $@;
my $tests;
plan tests => $tests;
@@ -17,8 +17,8 @@ BEGIN { $tests += 2 * 3 };
my $t = Test::Mojo->new('SrvMngr');
$t->ua->max_redirects(1);
$t->get_ok('/')->status_is(200)->content_like(qr/SME Server 10/);
$t->get_ok('/manual')->status_is(200)->content_like(qr/SME Server 10/);
$t->get_ok('/')->status_is(200)->content_like(qr/SME Server 11/);
$t->get_ok('/manual')->status_is(200)->content_like(qr/SME Server 11/);
BEGIN { $tests += 5 * 2 };
my @panels = qw/ Initial Login Manual Support Request /;

View File

@@ -0,0 +1,38 @@
Configuration report created {$report_creation_time}
==================
Base configuration
==================
SME server version: {$releaseversion}
SME server mode: {$systemmode}
SME server previous mode: {$previoussystemmode }
Running Kernel: {$curkernel}
===========================
New RPMs not in base system
===========================
{ foreach $i (@newrpms) {
$OUT .= "$i";
}
}
===========================
Custom and modified templates
===========================
{ foreach $i (@templates) {
$OUT .= "$i";
}
}
===========================
Modified events
===========================
{ foreach $i (@events) {
$OUT .= "$i";
}
}
=======================
Additional repositories
=======================
{ foreach $r (@repositories) {
$OUT .= "$r";
}
}
DONE!

View File

@@ -0,0 +1,51 @@
.datetime-config-row {
display: flex;
align-items: stretch;
margin-bottom: 1em;
}
.datetime-label-col {
background: #e8f3e2; /* light green */
padding: 1em 0em 0em 0em;
min-width: 30%;
display: flex;
align-items: flex-start;
justify-content: flex-end;
font-weight: bold;
border-radius: 4px 0 0 4px;
}
.datetime-label {
display:inline-flex;
}
.datetime-fields-col {
background: #fff;
padding: 1em;
flex: 1;
border: 1px solid #ccc;
border-left: none;
border-radius: 0 4px 4px 0;
}
.datetime-clock {
min-width: 20em;
display:inline-flex;
border:0px;
padding:5px;
}
.datetime-clock-label {
background-color:#e8f3e2;
display:inline-flex;
width:30%;
font-weight:bold;
text-align:right;
}
.ntp-test-result { font-weight: bold; }
.ntp-test-success { color: green; }
.ntp-test-error { color: red; }
.ntp-test-wait { color: #333; }

View File

@@ -1,90 +0,0 @@
/*
Generated by SM2Gen version: SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
*/
.Letsencrypt-panel {}
.name {}
.rout {}
.grou {}
.link2 {}
.link3 {}
.link4 {}
.endg {}
.subh2 {}
.read4 {}
.read5 {}
.read6 {}
.subh3 {}
.read1 {}
.read2 {}
.read3 {}
.subh4 {}
.tabl1 {}
thead .tabl1 {}
tbody .tabl1 {}
.name {}
.rout {}
.subh {}
.para1 {}
.sele1 {}
.sele2 {}
.sele3 {}
.sele4 {}
.sele5 {}
.sele6 {}
.sele7 {}
.emai8 {}
.subm9 {}
.name {}
.rout {}
.head {}
.subh {}
.text1 {}
.back2 {}
.name {}
.rout {}
.head {}
.subh {}
.text1 {}
.back2 {}
.name {}
.rout {}
.head {}
.subh {}
.read1 {}
.text2 {}
.back3 {}
.inline-buttons {
display: flex; /* Use flexbox to arrange items horizontally */
gap: 10px; /* Optional: Add space between buttons */
}
.inline-buttons .link {
/* Additional styling can be added here if needed */
}
.inline-buttons .link {
display: inline-block; /* Keep links as inline-block for button shape */
padding: 7px 14px; /* Adjusted padding to approximate 70% of the original */
margin: 0; /* Remove margin */
background-color: #efefef; /* Light gray background color */
color: black; /* Text color */
text-decoration: none; /* Remove underline */
border: 2px solid #bbb; /* Thin, light gray border */
border-radius: 3px; /* Slightly rounded corners */
font-size: 11.2px; /* Adjusted font size to approximate 70% of the original */
text-align: center; /* Center the text */
cursor: pointer; /* Pointer cursor on hover */ }
/* Hover and active effects for better interaction */
.inline-buttons .link:hover {
background-color: #d9d9d9; /* Darker shade on hover */
}
.inline-buttons .link:active {
background-color: #c0c0c0; /* Even darker shade on click */
}
span .label {
padding-top:13em;
}

View File

@@ -0,0 +1,43 @@
/* General styles for the module panel */
#module {
padding: 20px;
border: 1px solid #ccc;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* Debug information styling */
#module p {
font-family: monospace;
color: #555;
}
#module pre {
background-color: #eee;
padding: 10px;
border-radius: 5px;
}
/* Error message styling */
.sme-error {
color: #d9534f;
font-weight: bold;
margin-bottom: 15px;
}
/* Title styling */
#module h1 {
font-family: Arial, sans-serif;
color: #333;
text-align: center;
margin-bottom: 20px;
}
/* Content styling */
.module-content {
font-family: Georgia, serif;
font-size: 13px;
line-height: 1.2;
color: #555;
}

View File

@@ -0,0 +1,505 @@
{
margin-left: 0;
}
a.alert {
color: red;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.item {
color: #00008b;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.item-current:hover, a.warn-current:hover {
border-color: #888;
}
a.item-current:link, a.warn-current:link,
a.item-current:visited, a.warn-current:visited,
a.item-current:active, a.warn-current:active,
a.item-current:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #fff;
border-color: #888;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.item:active, a.item-current:active,
a.warn:active, a.warn-current:active {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: white;
background: black;
text-decoration: none;
border-color: #000;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.item:hover, a.item-current:hover,
a.warn:hover, a.warn-current:hover {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
text-decoration: none;
background: #ccc;
border-color: #888;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.item:link, a.item-current:link,
a.warn:link, a.warn-current:link {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
text-align: left;
border-color: #e8f3e1;
margin: 0;
border-style: solid;
border-width: 1px;
padding: 0 10px 2px;
}
a.item:visited, a.item-current:visited,
a.warn:visited, a.warn-current:visited {
display: block;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
color: black;
background: #e8f3e1;
text-decoration: none;
border-color: #e8f3e1;
margin: 0;
border-style: solid;
border-width: 1px;
padding-right: 10px;
padding-left: 10px;
padding-bottom: 2px;
text-align: left;
}
a.section-title {
display: inline-block;
color: #6CA345;
padding-left: 5px;
padding-right: 5px;
line-height: 18px;
font-weight: bold;
}
a.sl {
color: green;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #e8f3e1;
}
a.update {
color: red;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background: #98d36e;
}
a.warn:link, a.warn-current:link,
a.warn:visited, a.warn-current:visited,
a.warn:active, a.warn-current:active,
a.warn:hover, a.warn-current:hover {
background-image: url("/server-common/warn.gif");
background-repeat: no-repeat;
background-position: 10px;
padding-left: 25px;
}
a:active {
color: #606060;
text-decoration: none;
}
a:hover {
color: #F00;
text-decoration: none;
}
a:link {
color: #006921;
text-decoration: none;
}
a:visited {
color: #063;
text-decoration: none;
}
body {
background-color: #FFF;
color: #000;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
border-width: 0;
}
body, body.main {
margin: 5px 20px 5px 5px;
}
body, body.menu {
margin: 0 0 0 2px;
}
body.header {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #bee6a2;
margin: 0;
}
body.main {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #fff;
color: #000;
}
body.menu {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #e8f3e1;
}
div.error, div.sme-error, span.error, span.sme-error {
color: red;
background-color: #f9f9f9;
border-width: 1px;
border-style: solid;
border-color: red;
padding: 10px;
border-radius: 10px;
}
form {
margin-top: 2px;
margin-bottom: 2px;
}
h1, .h1 {
font-family: Verdana, Tahoma, sans-serif;
color: #333;
font-size: 18px;
margin-bottom: 4px;
margin-top: 12px;
}
h2, .h2 {
font-family: Verdana, Tahoma, sans-serif;
color: #333;
font-size: 14px;
margin-bottom: 3px;
margin-top: 12px;
}
h3, .h3 {
font-family: Verdana, Tahoma, sans-serif;
color: #333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 12px;
}
h4, .h4 {
font-family: Verdana, Tahoma, sans-serif;
font-style: italic;
color: #333;
font-size: 12px;
margin-bottom: 2px;
margin-top: 10px;
}
hr.sectionbar {
color: #8ebe43;
background-color: #8ebe43;
height: 1px;
width: 80%;
border: 0;
}
hr.sme-copyrightbar {
color: #8ebe43;
background-color: #8ebe43;
height: 1px;
width: 100%;
border: 0;
}
input.action {
margin-left: 0;
background-color: #bee6a2;
color: darkgreen;
border-radius: 8px;
border: 2px solid #4CAF50;
display: flex;
justify-content: center;
align-items: center;
}
input.action2 {
margin-left: 0;
color: black;
background-color: #d4d0c8;
display: flex;
justify-content: center;
}
input.action:active {
background-color: #3e8e41;
transform: translate(-2px,2px);
}
input.action:hover {
background-color: #3e8e41;
color: white;
}
input.field-with-error {
background-color: #fd9e7e;
}
label.field-with-error {
color: #dd7e5e;
}
ol, ul, li {
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
font-weight: normal;
color: black;
}
p {
margin-top: 8px;
margin-bottom: 2px;
}
span {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
span.data {
padding: 2px;
font-weight: bold;
margin-left: 0;
}
span.data2 {
padding: 2px;
}
span.label {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1;
width: 30%;
text-align: right;
}
span.label2 {
display: inline-block;
font-weight: bold;
background-color: #e8f3e1;
text-align: right;
}
table, tr, td, div, p, form {
color: #000;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
table.sme-border {
border-collapse: collapse;
border: 2px solid #cccccc;
empty-cells: show;
margin: 5px;
}
table.sme-layout {
border-collapse: collapse;
margin-bottom: 2px;
margin-top: 2px;
}
table.sme-noborders {
padding: 0;
margin: 0 0 20px;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
td {
text-align: left;
}
td.darkgrey {
background-color: #888;
}
td.label {
font-weight: bold;
background-color: #e8f3e1;
width: 30%;
text-align: right;
}
td.menu-cell {
margin: 0;
padding: 0;
}
td.section {
padding-bottom: 2px;
padding-top: 8px;
background-color: #e8f3e1;
}
td.sme-border a, td.sme-border-right a, td.sme-border-center a {
font-size: 10px;
}
td.sme-border, td.sme-border-warning, td.sme-border-right, td.sme-border-center {
border: 1px solid #cccccc;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
font-weight: normal;
color: #000;
text-align: left;
padding: 3px 2px;
}
td.sme-border-center {
text-align: center;
}
td.sme-border-right {
text-align: right;
}
td.sme-border-warning {
color: red;
}
/* sme-layout* : Used for top-level layout */
table.sme-layout {
border-collapse: collapse;
margin-bottom: 2px;
margin-top: 2px;
}
tr.sme-layout {
border: 1px solid #dddddd;
}
td.sme-layout {
border: 1px solid #dddddd;
}
td.sme-noborders-content {
text-align: left;
vertical-align: top;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
}
td.sme-noborders-info, div.sme-noborders-info {
text-align: left;
vertical-align: top;
}
td.sme-noborders-label {
font-weight: bold;
text-align: right;
background-color: #e8f3e1;
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
width: 33%;
}
td.sme-radiobutton {
width: 30px;
}
th.sme-border {
border: 1px;
background-color: #bee6a2;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
font-weight: bold;
color: #000;
text-align: center;
vertical-align: bottom;
padding: 3px;
}
th.sme-layout {
border: 1px;
background-color: #e8f3e1;
font-family: Verdana, Tahoma, sans-serif;
font-size: 9pt;
font-weight: bold;
color: #000;
text-align: right;
padding: 4px;
}
tr.sme-layout {
border: 1px;
}
ul {
list-style-type: circle;
}
div.success, span.success {
color: #006400;
border-width: 1px;
border-style: solid;
border-color: #006400 ;
padding: 10px;
border-radius: 10px;
}
div.roundcube #roundcube{
width:100%;
height:600px;
}

View File

@@ -0,0 +1,283 @@
/* css/sme-password.css */
.input-container {
position: relative;
display: inline-block;
}
.sme-password {
padding-right: 5px; /* Ensure space for the toggle icon */
}
.toggle-password {
position: absolute;
right: 4px; /* Position it towards the right */
top: 50%; /* Center vertically */
transform: translateY(-50%); /* Adjust for exact centering */
cursor: pointer;
width: 20px; /* Set the width of the icon */
height: 20px; /* Set the height of the icon */
}
.module {
padding: 20px;
border: 1px ;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
margin-left: 10px !important;
margin-top: 10px;
}
.sme-copyright {
color: #777;
font-family: Verdana, Tahoma, sans-serif;
font-size: 10px;
}
.logo {
height: 142%;
width: auto;
margin-left: -16px;
}
.gradient-panel {
width: 100%;
height: 40px;
background: linear-gradient(to right, white ,#c0e7a5 );
display: flex;
align-items: center;
position: relative;
}
.sme-error {
color: #d9534f;
display: block;
background-color: #fff;
border-width: 1px;
border-style: solid;
border-color: red;
padding: 2px;
font-weight: bold;
margin-bottom: 15px;
}
.login-button {
position: absolute;
left: 7%;
transform: translateX(-50%);
background-color: #4caf50b8;
color: white !important;
border: none;
padding: 8px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
cursor: pointer;
border-radius: 4px;
margin-left: 77%;
}
.sme-warning {
color: orange;
display: block;
background-color: #fff;
border-width: 1px;
border-style: solid;
border-color: orange;
padding: 2px;
}
.infobar {
font-family: Verdana, Tahoma, sans-serif;
font-size: 11px;
background-color: #98d36e;
}
.module-content {
font-family: Georgia, Garamond, serif;
font-size: 13px;
line-height: 1.2;
color: #555;
}
#help-button {
text-decoration: none;
font-size: 20px;
padding: 8px;
background-color: #98d36e;
border-radius: 4px;
color: #000;
}
/*
#module {
padding: 20px;
border: 1px;
border-radius: 10px;
background-color: #f9f9f9;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
*/
#container {
max-width: 100%;
position: relative;
margin: auto;
}
#header2 {
width:96%;
margin-left: 1px;
margin-top: 4px;
}
#main {
margin-left: 200px;
padding: 10px;
}
#central {
padding: 5px;
}
#footer {
padding-left: 5px;
}
#header {
width: 100%;
margin: auto;
}
#navigation {
width: 190px;
position: absolute;
padding: 5px;
background-color: #E8F3E1;
overflow: auto;
margin-top:20px;
}
#footer img {
float: right;
position: fixed;
/*margin-left: 40%;*/
}
.flag-style {
position: absolute;
transform: translateY(-50%);
left: 95%;
/*right: 20px;
*/
width: 24px;
height: 14px;
display: inline-block;
vertical-align: middle;
}
/* flag container*/
#flag-container span {
font-size: 24px;
display: flex; /* Allows for easy centering */
justify-content: center; /* Center horizontally */
align-items: center; /* Center vertically */
width: 100%; /* Full width of parent */
height: 24px; /* Set a fixed height */
border: 1px solid #ccc; /* Light gray border */
border-radius: 5px; /* Rounded corners */
cursor: default; /* Prevent text cursor */
}
.fallback-box {
display: inline-block; /* Make it inline-block to fit around the content */
border: 2px solid gray; /* Change the border color as desired */
padding: 10px; /* Add some padding */
border-radius: 10px; /* Round the corners of the box */
font-size: 60px; /* Adjust size if needed */
margin-top: 10px; /* Add some margin */
text-align: center; /* Center text inside the box */
}
table.sme-border {
border-collapse: collapse;
border: 2px solid #cccccc;
empty-cells: show;
margin: 5px 5px 5px 2px;
}
td.sme-border, td.sme-border-warning, td.sme-border-right, td.sme-border-center {
border: 1px solid #cccccc;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: normal;
color: #000000;
text-align: left;
padding-left: 2px;
padding-right: 2px;
padding-top: 3px;
padding-bottom: 3px;
}
td.sme-border-warning {
color: red;
}
td.sme-border-right {
text-align: right;
}
td.sme-border-center {
text-align: center;
}
th.sme-border {
border: 1px solid #cccccc;
background-color: #bee6a2;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10px;
font-weight: bold;
color: #000000;
text-align: center;
vertical-align: bottom;
padding-left: 3px;
padding-right: 3px;
padding-top: 3px;
padding-bottom: 3px;
/*border-width: 1px;
border-style: solid;
border-color: #F2F0EE #75736E #75736E #F2F0EE ;
*/
}
td.sme-border a, td.sme-border-right a, td.sme-border-center a {
font-size: 10px;
}
th.sme-layout {
border: 1px solid #8ebe43;
background-color: #bee6a2;
}
table.sme-border {
border: 2px solid #dddddd;
}
td.sme-border-warning,
td.sme-border-right,
td.sme-border-center {
border: 1px solid #dddddd;
}
td.sme-border-right {text-align: right;}
td.sme-border-center {text-align: center;}
th.sme-border {
border: 1px solid #dddddd;
background-color: #e8f3e1;
}
.no-visited-state {
color: inherit;
/* Or specify the desired color */
text-decoration: none;
/* Or any other style you want to reset */
}
.no-visited-state:visited {
color: inherit;
/* Or specify the desired color */
text-decoration: none;
/* Or any other style you want to reset */
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,101 @@
document.addEventListener('DOMContentLoaded', function() {
var select = document.getElementById('time_mode_select');
var ntpSection = document.getElementById('ntp_section');
var manualSection = document.getElementById('manual_section');
function toggleSections() {
if (select.value === 'dat_manually_set') {
ntpSection.style.display = 'none';
manualSection.style.display = 'block';
} else {
ntpSection.style.display = 'block';
manualSection.style.display = 'none';
}
}
select.addEventListener('change', toggleSections);
toggleSections(); // Set initial state
});
document.addEventListener('DOMContentLoaded', function() {
// Parse the initial server time from the input value
const clockElement = document.getElementById('real-time-clock');
if (!clockElement) return;
// Get the initial server time from the input's value
let serverTime = new Date(clockElement.value.replace(' ', 'T'));
function updateDateTime() {
// Format the date/time string as desired
const daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const dayOfWeek = daysOfWeek[serverTime.getDay()];
const month = months[serverTime.getMonth()];
const day = serverTime.getDate();
const year = serverTime.getFullYear();
let hours = serverTime.getHours();
const ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12 || 12;
const minutes = serverTime.getMinutes().toString().padStart(2, '0');
const seconds = serverTime.getSeconds().toString().padStart(2, '0');
const dateTimeString = `${dayOfWeek}, ${month} ${day}, ${year} ${hours}:${minutes}:${seconds} ${ampm}`;
clockElement.value = dateTimeString;
// Advance serverTime by one second
serverTime.setSeconds(serverTime.getSeconds() + 1);
}
updateDateTime();
setInterval(updateDateTime, 1000);
});
document.addEventListener('DOMContentLoaded', function() {
const btn = document.getElementById('test-ntp-btn');
const input = document.getElementById('ntpserver');
const result = document.getElementById('ntp-test-result');
btn.addEventListener('click', function() {
const server = input.value.trim();
result.className = 'ntp-test-result'; // reset
if (!server) {
result.textContent = "Please enter a server address.";
result.classList.add('ntp-test-error');
return;
}
result.textContent = "Testing...";
result.classList.add('ntp-test-wait');
fetch('/smanager/datetimet', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({ ntpserver: server })
})
.then(response => {
if (!response.ok) {
// HTTP error, e.g., 404, 500
throw new Error(`HTTP error: ${response.status} ${response.statusText}`);
}
return response.json();
})
.then(data => {
result.className = 'ntp-test-result'; // reset
if (data.success) {
result.textContent = `Server time: ${data.time}`;
result.classList.add('ntp-test-success');
} else {
result.textContent = `Error: ${data.error}`;
result.classList.add('ntp-test-error');
}
})
.catch(error => {
// Network error or thrown HTTP error
result.className = 'ntp-test-result ntp-test-error';
result.textContent = `Request failed: ${error.message}`;
});
});
});

View File

@@ -0,0 +1,25 @@
document.addEventListener('DOMContentLoaded', function() {
const analysisType = document.getElementById('analysis_type');
const messageIdGroup = document.getElementById('message_id_group');
const emailAddressGroup = document.getElementById('email_address_group');
// Initially hide both controls
messageIdGroup.style.display = 'none';
emailAddressGroup.style.display = 'none';
analysisType.addEventListener('change', function() {
// Hide both controls first
messageIdGroup.style.display = 'none';
emailAddressGroup.style.display = 'none';
// Show the relevant control based on the selected option
switch(this.value) {
case 'trace_message':
messageIdGroup.style.display = 'block';
break;
case 'user_activity':
emailAddressGroup.style.display = 'block';
break;
}
});
});

View File

@@ -74,10 +74,8 @@
</p><br>
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('bac_UPDATE_CONF'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -30,10 +30,8 @@
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('bac_RESTORE_FROM_TAPE'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -44,12 +44,10 @@
</span></p>
%= hidden_field 'Function' => $bac_datas->{'function'} . '1'
<div class='center'>
%= submit_button $c->l('NEXT'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -148,9 +148,7 @@
%= hidden_field 'Function' => $bac_datas->{function}
%= hidden_field 'VFSType' => $bac_datas->{vfstype}
<div class='center'>
%= submit_button $c->l('bac_UPDATE_CONF'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -38,9 +38,7 @@
</span><br><br>
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('bac_RESTORE_FROM_WORKSTN'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -29,9 +29,7 @@
%=l 'bac_YOU_MUST_REBOOT'
</p>
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('bac_REBOOT'), class => 'action'
</div>
% end
</div>

View File

@@ -39,12 +39,10 @@
</span><br>
<br>
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('PERFORM'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -41,9 +41,7 @@
%= hidden_field 'Backupset' => $bac_datas->{'backupset'}
%= hidden_field 'Filterexp' => $bac_datas->{'filterexp'}
<div class='center'>
%= submit_button $c->l('PERFORM'), class => 'action'
</div>
% end

View File

@@ -24,9 +24,7 @@
%= form_for '/backupd' => (method => 'POST') => begin
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('NEXT'), class => 'action'
</div>
% end

View File

@@ -44,10 +44,8 @@
<br><br>
%= hidden_field 'Function' => $bac_datas->{'function'} . '1'
<div class='center'>
%= submit_button $c->l('bac_VERIFY'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -28,10 +28,8 @@
%= hidden_field 'Function' => $bac_datas->{'function'}
<div class='center'>
%= submit_button $c->l('NEXT'), class => 'action'
</div>
% end
</div>
% end
% end

View File

@@ -1,6 +1,6 @@
<%
my $backups = esmith::BackupHistoryDB->open;
my $backups = esmith::BackupHistoryDB->open; # no UTF8
my $now = time();
my $backup_rec = $backups->new_record($now, {
type => 'backup_record', BackupType => 'desktop',
@@ -11,42 +11,52 @@
# The events handle cases where mysqld is not enabled, and/or is not running.
my $status = system("/sbin/e-smith/signal-event", "pre-backup", "desktop");
if ($status) {
desktopBackupRecordStatus($backup_rec, 'pre-backup', $status);
return ($c->l('bac_OPERATION_STATUS_REPORT').
$c->l('bac_ERR_PRE_BACKUP'));
$c->desktopBackupRecordStatus($backup_rec, 'pre-backup', $status);
return ($c->l('bac_OPERATION_STATUS_REPORT').$c->l('bac_ERR_PRE_BACKUP'));
}
my $clvl = $c->stash('compressionlevel');
my $cmd = "/bin/tar --directory / --create @{$c->stash('directories')} --file=-"
. "@{$c->stash('exclude')} | /usr/bin/gzip $clvl ";
my $cmd = "/bin/tar --create --file=- --directory / @{$c->stash('exclude')} "
. "@{$c->stash('directories')} | /usr/bin/gzip $clvl ";
my $success = open my $fh, '-|', $cmd;
unless ($success) { return "Error dowload command."; };
# Write chunk
$c->res->headers->content_type('application/x-tar');
$c->res->headers->content_disposition(qq/attachment; filename="smeserver.tgz"/);
my $cb;
$cb = sub {
my $c = shift;
my $size = 500 * 1024;
my $length = sysread($fh, my $buffer, $size);
unless ($length) {
close $fh;
undef $cb;
$c->finish;
return;
}
$c->write_chunk($buffer, $cb);
};
$c->$cb;
#unless ($success) { return "Error download command."; };
if ($success) {
# Try with download plugin - seems to fail to complete download and also
# name of file deposited is not as required.
#my $output = do { local $/; <$fh> };
#close $fh;
#$c->render_file(
#data => $output,
#filename => 'output.txt',
#content_type => 'text/plain'
#);
# So organise it ourselves.
$c->res->headers->content_type('application/x-tar');
$c->res->headers->content_disposition(qq/attachment; filename="smeserver.tgz"/);
my $cb;
$cb = sub {
my $c = shift;
my $size = 500 * 1024;
my $length = sysread($fh, my $buffer, $size);
unless ($length) {
close $fh;
undef $cb;
$c->finish;
return;
}
$c->write_chunk($buffer, $cb);
};
$c->$cb;
} else {
$c->render(text => "Failed to execute command: $!", status => 500);
}
# Remove the dumped tables.
$status = system("/sbin/e-smith/signal-event", "post-backup", "desktop");
if ($status) {
desktopBackupRecordStatus($backup_rec, 'post-backup', $status);
die ($c->l('bac_ERR_POST_BACKUP'),"\n");
$c->desktopBackupRecordStatus($backup_rec, 'post-backup', $status);
die ($c->l('bac_ERR_POST_BACKUP'),"\n");
}
$now = time();
@@ -54,3 +64,4 @@
$backup_rec->set_prop('Result', "0");
%>
1;

View File

@@ -70,12 +70,10 @@
</span></p>
<br>
<div class='center'>
%= submit_button $c->l('PERFORM'), class => 'action'
</div>
%= submit_button $c->l('PERFORM'), class => 'action'
% end
</div>
% end
% end

View File

@@ -18,9 +18,16 @@
<% my $btn = l('bugr_Download this report'); %>
%= form_for 'bugreportD' => (method => 'POST') => begin
%= submit_button "$btn", class => 'action'
%= hidden_field 'trt' => $bugr_datas->{trt}
% end
%= submit_button "$btn", class => 'action'
%= hidden_field 'trt' => $bugr_datas->{trt}
% end
% my $out = "================== <br />";
% $out .= "Boot anaysis image (right click and save image to download)<br />";
% $out .= "================== <br />";
% $out .= "<img src='images/boot.svg' alt='boot timing image' width=95% >";
<br><%= $c->render_to_string(inline=>$out) %><br>
</div>

View File

@@ -1,125 +1,149 @@
% layout 'default', title => "Sme server 2 - datetime";
% layout 'default', title => 'Sme server 2 - datetime';
% content_for 'module' => begin
<div id='module' class='module datetime-panel'>
%= javascript 'js/datetime.js'
%= stylesheet 'css/datetime.css'
<div id='module' class='module datetime-panel'>
% if (config->{debug} == 1) {
<p>
%= dumper $c->current_route
%= dumper $dat_data
</p>
% }
% if (config->{debug} == 1) {
<p>
%= dumper $c->current_route
%= dumper $dat_datas
</p>
% }
%if ($c->stash('first')) {
<br><p>
%=$c->render_to_string(inline =>$c->l($c->stash('first')))
</p>
%} elsif ($c->stash('success')) {
<div class='success '>
%= $c->l($c->stash('success'));
</div>
%} elsif ($c->stash('error')) {
<div class='sme-error'>
%= $c->l($c->stash('error'));
</div>
%}
% if ( stash 'error' ) {
<br><div class=sme-error>
%= $c->render_to_string(inline => stash 'error')
<h1><%= $title %></h1><br>
%= $modul
<% my $btn = l('SAVE'); %>
<br /><br />
<span>
%= label_for 'real-time-clock' => $c->l('dat_The_time_is_currently'), class => 'datetime-clock-label'
</span><span class=data2>
<!--
<div id="real-time-clock"></div>
-->
%= text_field 'clock', id => 'real-time-clock', readonly => 'readonly', class => 'datetime-clock' , value => $dat_data->{currentdatetime}
</span>
% if ($dat_data->{ntpstatus} eq 'disabled') {
<div class='datetime-set-ntp'>
%=l 'dat_NTP_ENABLE_DESC'
<br>
</div>
% } else {
% my $current_year = $dat_data->{year};
% my $year_options = [ map { [ $_, $_ ] } ($current_year..($current_year+30)) ];
% my $month_options = [ map { [ sprintf('%02d', $_), sprintf('%02d', $_) ] } (1..12) ];
% my $hour_options = [ map { [ sprintf('%02d', $_), sprintf('%02d', $_) ] } (0..23) ];
% my $mode_options = [
% [ $c->l('dat_ntp_server'), 'dat_ntp_server' ],
% [ $c->l('dat_manually_set'), 'dat_manually_set' ]
% ];
<h2><%= $c->l('Time Configuration') %></h2>
%= form_for "datetimeu" => (method => 'post') => begin
%= hidden_field 'Old_ntpstatus' => $dat_data->{ntpstatus};
%= hidden_field 'trt' => $dat_data->{trt};
<span class=label>
%= label_for time_mode => $c->l('Time Setting Mode:')
</span><span class=data2>
% param 'time_mode' => $dat_data->{time_mode} unless param 'time_mode';
%= select_field time_mode => ($mode_options, id => 'time_mode_select')
</span>
<div id='ntp_section'>
<p>
%= $c->l('dat_NTP_CONFIGURE_DESC')
</p>
<div class='datetime-config-row'>
<div class='datetime-label-col'>
<span class='datetime-label'>
%= label_for ntpserver => $c->l('dat_NTP_Server_URL')
</span>
</div>
<div class=datetime-fields-col>
% my $server_check = '^([a-zA-Z0-9][a-zA-Z0-9\.\-]{0,253}[a-zA-Z0-9]|(\d{1,3}\.){3}\d{1,3})$';
% param 'ntpserver' => $dat_data->{ntpserver} unless param 'ntpserver';
%= text_field ntpserver => placeholder => 'e.g. smeserver.pool.ntp.org', id => 'ntpserver', pattern => $server_check, title => 'Enter a valid hostname or IPv4 address', required => 'required'
<button type="button" id="test-ntp-btn" class="btn btn-primary ml-2">Test Server</button>
<span id="ntp-test-result" class="ntp-test-result ml-2"></span>
</div>
</div>
</div>
<div id='manual_section'>
<p>
%= $c->l('dat_NTP_DISABLE_DESC')
</p>
<div class='datetime-config-row'>
<div class='datetime-label-col'>
<span class='datetime-label'>
%= label_for 'datetime_manual' => $c->l('dat_set_manually')
</span>
</div>
<div class='datetime-fields-col' id='datetime_manual'>
<fieldset>
<legend><%= $c->l('Date') %></legend>
%= label_for year => $c->l('Year:')
% param 'year' => ($dat_data->{year}) unless param 'year';
%= select_field year => ($year_options, id => 'year'), required => 'required'
&nbsp;
%= label_for month => $c->l('Month:')
% param 'month' => ($dat_data->{month}) unless param 'month';
%= select_field month => ($month_options, id => 'month'), required => 'required'
&nbsp;
%= label_for day => $c->l('Day:')
% param 'day' => ($dat_data->{day}) unless param 'day';
%= text_field day => id => 'day', size => 2, maxlength => 2, placeholder => 'DD', pattern => '^(0[1-9]|[12][0-9]|3[01])$', title => 'Day (01-31)', required => 'required', inputmode => 'numeric', autocomplete => 'off'
</fieldset>
<fieldset>
<legend><%= $c->l('Time') %></legend>
%= label_for hour => $c->l('Hour:')
% param 'hour' => ($dat_data->{hour}) unless param 'hour';
%= select_field hour => ($hour_options, id => 'hour'), required => 'required'
&nbsp;
%= label_for minute => $c->l('Minute:')
% param 'minute' => ($dat_data->{minute}) unless param 'minute';
%= text_field minute => id => 'minute', size => 2, maxlength => 2, placeholder => 'MM', pattern => '^[0-5][0-9]$', title => 'Minute (00-59)', required => 'required', inputmode => 'numeric', autocomplete => 'off'
&nbsp;
%= label_for second => $c->l('Second:')
% param 'second' => ($dat_data->{second}) unless param 'second';
%= text_field second => id => 'second', size => 2, maxlength => 2, placeholder => 'SS', pattern => '^[0-5][0-9]$', title => 'Second (00-59)', required => 'required', inputmode => 'numeric', autocomplete => 'off'
</fieldset>
</div>
</div>
<div class='datetime-config-row'>
<div class='datetime-label-col'>
<span class='datetime-label'>
%=l 'dat_TZ'
</span>
</div>
<div class='datetime-fields-col' id='datetime_manual'>
% param 'Timezone' => $c->getTimezone() unless param 'Timezone';
%= select_field 'Timezone' => $c->getZone_list(), class => 'input'
</div>
</div>
</div>
%= submit_button $btn, class => 'action'
% end
% }
</div>
%}
<h1><%= $title %></h1><br>
%= $modul
<% my $btn = l('SAVE'); %>
%= form_for '/datetime' => (method => 'POST') => begin
<p>
%= hidden_field 'Old_ntpstatus' => $dat_datas->{ntpstatus};
% param 'Ntpstatus' => $dat_datas->{ntpstatus} unless param 'Ntpstatus';
%= radio_button Ntpstatus => 'enabled'
<span class=label>
%=l 'dat_NTP_CONFIGURE_TITLE'
</span>
<br>
% if ($dat_datas->{ntpstatus} eq 'disabled') {
<div class='datetime-set-ntp'>
%=l 'dat_NTP_ENABLE_DESC'
<br>
</div>
% } else {
<div class='datetime-set-ntp'>
%=l 'dat_NTP_CONFIGURE_DESC'
<br><br>
<p>
%=l 'dat_CURRENT_SETTING'
<b>
%= $dat_datas->{now_string}
</b>
</p>
<p>
<br>
<span class=label>
%=l 'dat_NTP_SERVER'
</span><span class=data2>
%= text_field 'Ntpserver' => $dat_datas->{ntpserver}, class => 'input'
</span>
</p>
</div>
% }
%= radio_button Ntpstatus => 'disabled'
<span class=label datetime-set-ntp>
%=l 'dat_NTP_DISABLE_TITLE'
</span>
% if ($dat_datas->{ntpstatus} eq 'enabled') {
<br><BR>
<div class='datetime-set-ntp'>
%=l 'dat_NTP_DISABLE_DESC'
</div>
% } else {
<div class='datetime-set-ntp'>
<br>
</p>
<p>
%=l 'dat_CURRENT_SETTING'
<b>
%= $dat_datas->{now_string}
</b>
<br>
<span class=label>
%=l 'dat_NEW_M/D/Y'
</span><span class=data2>
% param 'Month' => $dat_datas->{month} unless param 'Month';
%= select_field 'Month' => $c->getMonth_list(), class => 'input'
</span><span class=data2>
% param 'Day' => $dat_datas->{day} unless param 'Day';
%= text_field 'Day', size => '2', class => 'input'
</span><span class=data2>
% param 'Year' => $dat_datas->{year} unless param 'Year';
%= text_field 'Year', size => '4', class => 'input'
</span>
<br>
<span class=label>
%=l 'dat_NEW_H/M/S'
</span><span class=data2>
% param 'Hour' => $dat_datas->{hour} unless param 'Hour';
%= text_field 'Hour', size => '2', class => 'input'
</span><span class=data2>
% param 'Minute' => $dat_datas->{minute} unless param 'Minute';
%= text_field 'Minute', size => '2', class => 'input'
</span><span class=data2>
% param 'Second' => $dat_datas->{second} unless param 'Second';
%= text_field 'Second', size => '2', class => 'input'
</span>
<br>
<span class=label>
%=l 'dat_AM/PM_AND_TZ'
</span><span class=data2>
% param 'Ampm' => $dat_datas->{ampm} unless param 'Ampm';
%= select_field 'Ampm' => ['AM', 'PM'], class => 'input'
</span><span class=data2>
% param 'Timezone' => $c->getTimezone() unless param 'Timezone';
%= select_field 'Timezone' => $c->getZone_list(), class => 'input'
</span>
</p>
</div>
% }
<p>
<br>
%= submit_button "$btn", class => 'action'
</p>
% end
</div>
%end
% end
1;

View File

@@ -33,7 +33,7 @@
%= select_field 'EmailUnknownUser' => $c->get_emailunknownuser_opt(), class => 'input'
</span></p>
<hr class='menubar' />
<!--<hr class='menubar' />-->
<h2>
%=l 'mai_TITLE_DELEGATE'
</h2>
@@ -47,7 +47,7 @@
%= text_field 'DelegateMailServer', class => 'input'
</span></p>
<hr class='sectionbar' />
<!--<hr class='sectionbar' />-->
<h2>
%=l 'mai_TITLE_SMARTHOST'
</h2>
@@ -89,4 +89,4 @@
% end
</div>
%end
%end

View File

@@ -92,7 +92,7 @@
%= select_field 'uSMTPAuth' => $c->get_smtp_ssl_auth_opt(), class => 'input'
</span></p>
<hr class="sectionbar" />
<!--<hr class="sectionbar" />-->
<h2>
%=l 'mai_TITLE_SECONDARY'
</h2>

View File

@@ -47,9 +47,10 @@
</div>
%= hidden_field 'trt' => 'ACC'
% end
% end
<br>
<hr class="sectionbar" />
<!--<hr class="sectionbar" />-->
%= form_for 'emailsettings' => (method => 'POST') => begin
<p><span class=label>
@@ -76,9 +77,10 @@
</div>
%= hidden_field 'trt' => 'FIL'
% end
% end
<br>
<hr class="sectionbar" />
<!--<hr class="sectionbar" />-->
%= form_for 'emailsettings' => (method => 'POST') => begin
<p><span class=label>
@@ -118,8 +120,9 @@
%= hidden_field 'trt' => 'REC'
% end
<br>
<hr class="sectionbar" />
<!--<hr class="sectionbar" />-->
%= form_for 'emailsettings' => (method => 'POST') => begin
<p><span class=label>

View File

@@ -2,7 +2,7 @@
% content_for 'module' => begin
<div id="central" class="sme-error">
<div id="central" class="sme-error module">
<p><br>dev<br> Oups !!!
The page you were requesting
"<%= $self->req->url->path || '/' %>"
@@ -14,4 +14,4 @@
</p>
</div>
% end
% end

View File

@@ -8,7 +8,7 @@
</p>
% }
<div id='central' class='central initial-panel'>
<div id='central' class='central initial-panel module'>
% if ( stash 'error' ) {
<br><div class=sme-error>

View File

@@ -7,11 +7,18 @@
<title><%= $title %></title>
<link rel="made" href="mailto:bugs%40koozali.org">
<meta name="copyright" content="(head.tmpl)Copyright 2003-2004 Mitel Corporation">
%= stylesheet '/css/sme_core.css'
%= stylesheet '/css/sme_main.css'
%= stylesheet '/css/sme_menu.css'
%= stylesheet '/css/styles.css'
%= stylesheet '/css/sme-password.css'
%= stylesheet '/css/new_sme.css'
%= stylesheet '/css/new-sme-main.css'
%# Replaced by consolidated (and rationlised) CSS files as above March 2025
%#= stylesheet '/css/sme_core.css'
%#= stylesheet '/css/sme_main.css'
%#= stylesheet '/css/sme_menu.css'
%#= stylesheet '/css/styles.css'
%#= stylesheet '/css/sme-password.css'
%= content_for 'head_contrib'
% if (config 'hasJquery') {
%= include 'partials/_js_imports'
@@ -70,7 +77,7 @@
%= content 'js_toggleMenu'
% }
<div id="navigation" class="col-md-3">
<div id="navigation" class="col-md-3 module">
%= include 'partials/_nav_menu'
% if ( $c->is_logged_in ) {
%= include 'partials/_user_menu'
@@ -84,17 +91,17 @@
%= include 'partials/_info'
% if (flash 'success') {
<br><div class=success>
<br><div class="success module">
%= $c->render_to_string(inline => flash 'success')
</div>
% }
% if ( flash 'warning' ) {
<br><div class=sme-warning>
<br><div class="sme-warning module">
%= $c->render_to_string(inline => flash 'warning')
</div>
%}
% if ( flash 'error' ) {
<br><div class=sme-error>
<br><div class="sme-error module">
%= $c->render_to_string(inline => flash 'error')
</div>
%}

View File

@@ -1,69 +0,0 @@
%#
%# Generated by SM2Gen version:0.8 Chameleon version:4.5.4 On Python:3.12.3 at 2024-12-01 15:22:43
%#
% layout 'default', title => "Sme server 2 - Letsencrypt certificate", share_dir => './';
%# css specific to this panel:
% content_for 'module' => begin
%= stylesheet '/css/letsencrypt.css'
<div id="module" class="module Letsencrypt-panel">
% if (config->{debug} == 1) {
<pre>
%= dumper $c->current_route
%= dumper $lets_data->{trt}
</pre>
% }
<h1><%=$title%></h1>
% if ( stash('modul')) {
%= $c->render_to_string(inline => stash('modul') );
% }
%if ($c->stash('first')) {
<br><p>
%=$c->render_to_string(inline =>$c->l($c->stash('first')))
</p>
%} elsif ($c->stash('success')) {
<div class='success '>
<h2><%=$c->l('lets_Status_Report') %></h2><p>
%= $c->l($c->stash('success'));
</p>
</div>
%} elsif ($c->stash('error')) {
<div class='sme-error'>
<h2><%=$c->l('lets_Error_Status_Report') %></h2><p>
%= $c->l($c->stash('error'));
</p>
</div>
%}
%#Routing to partials according to trt parameter.
%#This ought to be cascading if/then/elsif, but is easier to just stack the if/then's rather like a case statement'
% if ($lets_data->{trt} eq "LIST") {
%= include 'partials/_lets_LIST'
%}
% if ($lets_data->{trt} eq "PARAMS") {
%= include 'partials/_lets_PARAMS'
%}
% if ($lets_data->{trt} eq "CHECKALLDOMAINS") {
%= include 'partials/_lets_CHECKALLDOMAINS'
%}
% if ($lets_data->{trt} eq "CHECKALLENABLEDDOMAINS") {
%= include 'partials/_lets_CHECKALLENABLEDDOMAINS'
%}
% if ($lets_data->{trt} eq "CHECKONEDOMAIN") {
%= include 'partials/_lets_CHECKONEDOMAIN'
%}
</div>
%end

Some files were not shown because too many files have changed in this diff Show More