Add support for domain-level quota (total quota for a domain)

Based on a patch from W. Rossmann (W. Rossmann@SF),
https://sourceforge.net/tracker/index.php?func=detail&aid=2974928&group_id=191583&atid=937966
with some modifications, cleanup and adoptions to trunk (especially templates)

config.inc.php:
- new config option $CONF['domain_quota'] to enable/disable domain-level
  quota (default: enabled)
- new config option $CONF['domain_quota_default'] (default: 2 GB)

functions.inc.php - check_quota():
- add code to check the quota sum on a domain
- add optional parameter $username (to exclude that username from quota
  calculation, used by edit-mailbox)

edit-domain.php, create-domain.php,
admin_edit-domain.tpl, admin_create-domain.tpl:
- add input field and handling for domain-level quota

list-domain.php, overview-get.tpl, adminlistdomain.tpl:
- display allocated and allowed domain quota
- beautify quota and max_quota fields - display "unlimited" instead of "-1"

edit-mailbox.php:
- hand over username to check_quota()



git-svn-id: https://svn.code.sf.net/p/postfixadmin/code/trunk@1042 a1433add-5e2c-0410-b055-b7f2511e0802
pull/2/head
Christian Boltz 14 years ago
parent 091d15e58f
commit af6a1b6626

@ -182,10 +182,13 @@ function maildir_name_hook($domain, $user) {
$CONF['aliases'] = '10'; $CONF['aliases'] = '10';
$CONF['mailboxes'] = '10'; $CONF['mailboxes'] = '10';
$CONF['maxquota'] = '10'; $CONF['maxquota'] = '10';
$CONF['domain_quota_default'] = '2048';
// Quota // Quota
// When you want to enforce quota for your mailbox users set this to 'YES'. // When you want to enforce quota for your mailbox users set this to 'YES'.
$CONF['quota'] = 'NO'; $CONF['quota'] = 'NO';
// If you want to enforce domain-level quotas set this to 'YES'.
$CONF['domain_quota'] = 'YES';
// You can either use '1024000' or '1048576' // You can either use '1024000' or '1048576'
$CONF['quota_multiplier'] = '1024000'; $CONF['quota_multiplier'] = '1024000';

@ -46,7 +46,8 @@ $form_fields = array(
'fDescription' => array('type' => 'str', 'default' =>''), 'fDescription' => array('type' => 'str', 'default' =>''),
'fAliases' => array('type' => 'int', 'default' => $CONF['aliases']), 'fAliases' => array('type' => 'int', 'default' => $CONF['aliases']),
'fMailboxes' => array('type' => 'int', 'default' => $CONF['mailboxes']), 'fMailboxes' => array('type' => 'int', 'default' => $CONF['mailboxes']),
'fMaxquota' => array('type' => 'int', 'default' => $CONF['maxquota']), 'fMaxquota' => array('type' => 'int', 'default' => $CONF['maxquota']),
'fDomainquota' => array('type' => 'int', 'default' => $CONF['domain_quota_default']),
'fTransport' => array('type' => 'str', 'default' => $CONF['transport_default'], 'options' => $CONF['transport_options']), 'fTransport' => array('type' => 'str', 'default' => $CONF['transport_default'], 'options' => $CONF['transport_options']),
'fDefaultaliases' => array('type' => 'str', 'default' => 'on', 'options' => array('on', 'off')), 'fDefaultaliases' => array('type' => 'str', 'default' => 'on', 'options' => array('on', 'off')),
'fBackupmx' => array('type' => 'str', 'default' => 'off', 'options' => array('on', 'off')) 'fBackupmx' => array('type' => 'str', 'default' => 'off', 'options' => array('on', 'off'))
@ -80,6 +81,7 @@ if ($_SERVER['REQUEST_METHOD'] == "GET")
$tTransport = $fTransport; $tTransport = $fTransport;
$tAliases = $fAliases; $tAliases = $fAliases;
$tMaxquota = $fMaxquota; $tMaxquota = $fMaxquota;
$tDomainquota = $fDomainquota;
$tMailboxes = $fMailboxes; $tMailboxes = $fMailboxes;
$tDefaultaliases = $fDefaultaliases; $tDefaultaliases = $fDefaultaliases;
$tBackupmx = $fBackupmx; $tBackupmx = $fBackupmx;
@ -96,6 +98,7 @@ if ($_SERVER['REQUEST_METHOD'] == "POST")
$tAliases = $fAliases; $tAliases = $fAliases;
$tMailboxes = $fMailboxes; $tMailboxes = $fMailboxes;
if (isset ($_POST['fMaxquota'])) $tMaxquota = $fMaxquota; if (isset ($_POST['fMaxquota'])) $tMaxquota = $fMaxquota;
if (isset ($_POST['fDomainquota'])) $tDomainquota = $fDomainquota;
if (isset ($_POST['fTransport'])) $tTransport = $fTransport; if (isset ($_POST['fTransport'])) $tTransport = $fTransport;
if (isset ($_POST['fDefaultaliases'])) $tDefaultaliases = $fDefaultaliases; if (isset ($_POST['fDefaultaliases'])) $tDefaultaliases = $fDefaultaliases;
if (isset ($_POST['fBackupmx'])) $tBackupmx = $fBackupmx; if (isset ($_POST['fBackupmx'])) $tBackupmx = $fBackupmx;
@ -108,6 +111,7 @@ if ($_SERVER['REQUEST_METHOD'] == "POST")
$tAliases = $CONF['aliases']; $tAliases = $CONF['aliases'];
$tMailboxes = $CONF['mailboxes']; $tMailboxes = $CONF['mailboxes'];
$tMaxquota = $CONF['maxquota']; $tMaxquota = $CONF['maxquota'];
$tDomainquota = $CONF['domain_quota_default'];
if ($fBackupmx == "on") if ($fBackupmx == "on")
{ {
@ -120,7 +124,7 @@ if ($_SERVER['REQUEST_METHOD'] == "POST")
$sqlBackupmx = db_get_boolean(false); $sqlBackupmx = db_get_boolean(false);
} }
$sql_query = "INSERT INTO $table_domain (domain,description,aliases,mailboxes,maxquota,transport,backupmx,created,modified) VALUES ('$fDomain','$fDescription',$fAliases,$fMailboxes,$fMaxquota,'$fTransport','$sqlBackupmx',NOW(),NOW())"; $sql_query = "INSERT INTO $table_domain (domain,description,aliases,mailboxes,maxquota,quota,transport,backupmx,created,modified) VALUES ('$fDomain','$fDescription',$fAliases,$fMailboxes,$fMaxquota,$fDomainquota,'$fTransport','$sqlBackupmx',NOW(),NOW())";
$result = db_query($sql_query); $result = db_query($sql_query);
if ($result['rows'] != 1) if ($result['rows'] != 1)
{ {
@ -150,7 +154,8 @@ $smarty->assign ('pAdminCreate_domain_domain_text', $pAdminCreate_domain_domain_
$smarty->assign ('tDescription', $tDescription, false); $smarty->assign ('tDescription', $tDescription, false);
$smarty->assign ('tAliases', $tAliases); $smarty->assign ('tAliases', $tAliases);
$smarty->assign ('tMailboxes', $tMailboxes); $smarty->assign ('tMailboxes', $tMailboxes);
$smarty->assign ('tMaxquota', $tMaxquota,false); $smarty->assign ('tDomainquota', $tDomainquota);
$smarty->assign ('tMaxquota', $tMaxquota,false); # TODO: why is sanitize disabled? Should be just integer...
$smarty->assign ('select_options', select_options ($CONF ['transport_options'], array ($tTransport)),false); $smarty->assign ('select_options', select_options ($CONF ['transport_options'], array ($tTransport)),false);
$smarty->assign ('tDefaultaliases', ($tDefaultaliases == 'on') ? ' checked="checked"' : ''); $smarty->assign ('tDefaultaliases', ($tDefaultaliases == 'on') ? ' checked="checked"' : '');
$smarty->assign ('tBackupmx', ($tBackupmx == 'on') ? ' checked="checked"' : ''); $smarty->assign ('tBackupmx', ($tBackupmx == 'on') ? ' checked="checked"' : '');

@ -47,6 +47,7 @@ if ($_SERVER['REQUEST_METHOD'] == "GET")
$tDescription = $domain_properties['description']; $tDescription = $domain_properties['description'];
$tAliases = $domain_properties['aliases']; $tAliases = $domain_properties['aliases'];
$tMailboxes = $domain_properties['mailboxes']; $tMailboxes = $domain_properties['mailboxes'];
$tDomainquota = $domain_properties['quota'];
$tMaxquota = $domain_properties['maxquota']; $tMaxquota = $domain_properties['maxquota'];
$tTransport = $domain_properties['transport']; $tTransport = $domain_properties['transport'];
$tBackupmx = $domain_properties['backupmx']; $tBackupmx = $domain_properties['backupmx'];
@ -66,6 +67,11 @@ if ($_SERVER['REQUEST_METHOD'] == "POST")
} else { } else {
$fMaxquota = 0; $fMaxquota = 0;
} }
if (isset ($_POST['fDomainquota'])) {
$fDomainquota = intval($_POST['fDomainquota']);
} else {
$fDomainquota = $CONF['domain_quota_default'];
}
$fTransport = $CONF['transport_default']; $fTransport = $CONF['transport_default'];
if($CONF['transport'] != 'NO' && isset ($_POST['fTransport'])) { if($CONF['transport'] != 'NO' && isset ($_POST['fTransport'])) {
@ -101,7 +107,7 @@ if ($_SERVER['REQUEST_METHOD'] == "POST")
$sqltransport = "transport='$fTransport',"; $sqltransport = "transport='$fTransport',";
} }
$result = db_query ("UPDATE $table_domain SET description='$fDescription',aliases=$fAliases,mailboxes=$fMailboxes,maxquota=$fMaxquota,$sqltransport backupmx='$sqlBackupmx',active='$sqlActive',modified=NOW() WHERE domain='$domain'"); $result = db_query ("UPDATE $table_domain SET description='$fDescription',aliases=$fAliases,mailboxes=$fMailboxes,maxquota=$fMaxquota,quota=$fDomainquota,$sqltransport backupmx='$sqlBackupmx',active='$sqlActive',modified=NOW() WHERE domain='$domain'");
if ($result['rows'] == 1) if ($result['rows'] == 1)
{ {
header ("Location: list-domain.php"); header ("Location: list-domain.php");
@ -118,6 +124,7 @@ $smarty->assign ('tDescription', $tDescription);
$smarty->assign ('tAliases', $tAliases); $smarty->assign ('tAliases', $tAliases);
$smarty->assign ('tMailboxes', $tMailboxes); $smarty->assign ('tMailboxes', $tMailboxes);
$smarty->assign ('tMaxquota', $tMaxquota); $smarty->assign ('tMaxquota', $tMaxquota);
$smarty->assign ('tDomainquota', $tDomainquota);
$smarty->assign ('select_options', select_options($CONF['transport_options'], array($tTransport)), false); $smarty->assign ('select_options', select_options($CONF['transport_options'], array($tTransport)), false);
if ($tBackupmx) $smarty->assign ('tBackupmx', ' checked="checked"'); if ($tBackupmx) $smarty->assign ('tBackupmx', ' checked="checked"');
if ($tActive) $smarty->assign ('tActive', ' checked="checked"'); if ($tActive) $smarty->assign ('tActive', ' checked="checked"');

@ -117,7 +117,7 @@ if ($_SERVER['REQUEST_METHOD'] == "POST")
} }
if ($CONF['quota'] == "YES") if ($CONF['quota'] == "YES")
{ {
if (!check_quota ($fQuota, $fDomain)) if (!check_quota ($fQuota, $fDomain, $fUsername))
{ {
$error = 1; $error = 1;
$tName = $fName; $tName = $fName;

@ -678,29 +678,53 @@ function check_mailbox ($domain)
// Action: Checks if the user is creating a mailbox with the correct quota // Action: Checks if the user is creating a mailbox with the correct quota
// Call: check_quota (string domain) // Call: check_quota (string domain)
// //
function check_quota ($quota, $domain) function check_quota ($quota, $domain, $username="") {
{ global $CONF;
$rval = false;
$limit = get_domain_properties ($domain); $limit = get_domain_properties ($domain);
if ($limit['maxquota'] == 0) if ($limit['maxquota'] == 0)
{ {
return true; $rval = true;
} }
if (($limit['maxquota'] < 0) and ($quota < 0)) if (($limit['maxquota'] < 0) and ($quota < 0))
{ {
return true; $rval = true;
} }
if (($limit['maxquota'] > 0) and ($quota == 0)) if (($limit['maxquota'] > 0) and ($quota == 0))
{ {
return false; $rval = false;
} }
if ($quota > $limit['maxquota']) if ($quota > $limit['maxquota'])
{ {
return false; $rval = false;
} }
else else
{ {
return true; $rval = true;
} }
# TODO: detailed error message ("domain quota exceeded", "mailbox quota too big" etc.) via flash_error? Or "available quota: xxx MB"?
if (!$rval || $CONF['domain_quota'] != 'YES') {
return $rval;
} elseif ($limit['quota'] <= 0) {
$rval = true;
} else {
$table_mailbox = table_by_key('mailbox');
$query = "SELECT SUM(quota) FROM $table_mailbox WHERE domain = '" . escape_string($domain) . "'";
if ($username != "") {
$query .= " AND username != '" . escape_string($username) . "'";
}
$result = db_query ($query);
$row = db_row ($result['result']);
$cur_quota_total = divide_quota($row[0]); # convert to MB
if ( ($quota + $cur_quota_total) > $limit['quota'] ) {
$rval = false;
} else {
$rval = true;
}
}
return $rval;
} }

@ -73,7 +73,7 @@ $table_domain_fieldlist = "
"; ";
$query = " $query = "
SELECT $table_domain_fieldlist , COUNT( DISTINCT $table_mailbox.username ) AS mailbox_count SELECT $table_domain_fieldlist , COUNT( DISTINCT $table_mailbox.username ) AS mailbox_count, SUM( $table_mailbox.quota ) AS total_quota
FROM $table_domain FROM $table_domain
LEFT JOIN $table_mailbox ON $table_domain.domain = $table_mailbox.domain LEFT JOIN $table_mailbox ON $table_domain.domain = $table_mailbox.domain
$where $where
@ -103,6 +103,9 @@ $result = db_query($query);
while ($row = db_array ($result['result'])) { while ($row = db_array ($result['result'])) {
# add number of aliases to $domain_properties array. mailbox aliases do not count. # add number of aliases to $domain_properties array. mailbox aliases do not count.
$domain_properties [$row['domain']] ['alias_count'] = $row['alias_count'] - $domain_properties [$row['domain']] ['mailbox_count']; $domain_properties [$row['domain']] ['alias_count'] = $row['alias_count'] - $domain_properties [$row['domain']] ['mailbox_count'];
$domain_properties [$row['domain']] ['total_quota'] = (int) divide_quota($domain_properties [$row['domain']] ['total_quota']); # convert to MB
if ($domain_properties [$row['domain']] ['quota'] == -1) $domain_properties [$row['domain']] ['quota'] = $PALANG['pOverview_unlimited'];
if ($domain_properties [$row['domain']] ['maxquota'] == -1) $domain_properties [$row['domain']] ['maxquota'] = $PALANG['pOverview_unlimited'];
} }
$smarty->assign ('domain_properties', $domain_properties); $smarty->assign ('domain_properties', $domain_properties);

@ -24,6 +24,13 @@
<td><input class="flat" type="text" name="fMailboxes" value="{$tMailboxes}" /></td> <td><input class="flat" type="text" name="fMailboxes" value="{$tMailboxes}" /></td>
<td>{$PALANG.pAdminCreate_domain_mailboxes_text}</td> <td>{$PALANG.pAdminCreate_domain_mailboxes_text}</td>
</tr> </tr>
{if $CONF.domain_quota===YES}
<tr>
<td>{$PALANG.pAdminEdit_domain_quota}:</td>
<td><input class="flat" type="text" name="fDomainquota" value="{$tDomainquota}" /></td>
<td>{$PALANG.pAdminCreate_domain_maxquota_text}</td>
</tr>
{/if}
{if $CONF.quota===YES} {if $CONF.quota===YES}
<tr> <tr>
<td>{$PALANG.pAdminCreate_domain_maxquota}:</td> <td>{$PALANG.pAdminCreate_domain_maxquota}:</td>

@ -24,6 +24,13 @@
<td><input class="flat" type="text" name="fMailboxes" value="{$tMailboxes}" /></td> <td><input class="flat" type="text" name="fMailboxes" value="{$tMailboxes}" /></td>
<td>{$PALANG.pAdminEdit_domain_mailboxes_text}</td> <td>{$PALANG.pAdminEdit_domain_mailboxes_text}</td>
</tr> </tr>
{if $CONF.domain_quota===YES}
<tr>
<td>{$PALANG.pAdminEdit_domain_quota}:</td>
<td><input class="flat" type="text" name="fDomainquota" value="{$tDomainquota}" /></td>
<td>{$PALANG.pAdminEdit_domain_maxquota_text}</td>
</tr>
{/if}
{if $CONF.quota===YES} {if $CONF.quota===YES}
<tr> <tr>
<td>{$PALANG.pAdminEdit_domain_maxquota}:</td> <td>{$PALANG.pAdminEdit_domain_maxquota}:</td>

@ -14,7 +14,8 @@
<td>{$PALANG.pAdminList_domain_description}</td> <td>{$PALANG.pAdminList_domain_description}</td>
<td>{$PALANG.pAdminList_domain_aliases}</td> <td>{$PALANG.pAdminList_domain_aliases}</td>
<td>{$PALANG.pAdminList_domain_mailboxes}</td> <td>{$PALANG.pAdminList_domain_mailboxes}</td>
{if $CONF.quota==YES}<td>{$PALANG.pAdminList_domain_maxquota}</td>{/if} {if $CONF.quota==YES}<td>{$PALANG.pOverview_get_quota}</td>{/if}
{if $CONF.domain_quota==YES}<td>{$PALANG.pAdminList_domain_quota}</td>{/if}
{if $CONF.transport==YES}<td>{$PALANG.pAdminList_domain_transport}</td>{/if} {if $CONF.transport==YES}<td>{$PALANG.pAdminList_domain_transport}</td>{/if}
<td>{$PALANG.pAdminList_domain_backupmx}</td> <td>{$PALANG.pAdminList_domain_backupmx}</td>
<td>{$PALANG.pAdminList_domain_modified}</td> <td>{$PALANG.pAdminList_domain_modified}</td>
@ -28,6 +29,7 @@
<td>{$domain.alias_count} / {$domain.aliases}</td> <td>{$domain.alias_count} / {$domain.aliases}</td>
<td>{$domain.mailbox_count} / {$domain.mailboxes}</td> <td>{$domain.mailbox_count} / {$domain.mailboxes}</td>
{if $CONF.quota==YES}<td>{$domain.maxquota}</td>{/if} {if $CONF.quota==YES}<td>{$domain.maxquota}</td>{/if}
{if $CONF.domain_quota===YES}<td>{$domain.total_quota} / {$domain.quota}</td>{/if}
{if $CONF.transport==YES}<td>{$domain.transport}</td>{/if} {if $CONF.transport==YES}<td>{$domain.transport}</td>{/if}
<td>{$domain.backupmx}</td> <td>{$domain.backupmx}</td>
<td>{$domain.modified}</td> <td>{$domain.modified}</td>

@ -16,6 +16,7 @@
<td>{$PALANG.pOverview_get_aliases}</td> <td>{$PALANG.pOverview_get_aliases}</td>
<td>{$PALANG.pOverview_get_mailboxes}</td> <td>{$PALANG.pOverview_get_mailboxes}</td>
{if $CONF.quota===YES}<td>{$PALANG.pOverview_get_quota}</td>{/if} {if $CONF.quota===YES}<td>{$PALANG.pOverview_get_quota}</td>{/if}
{if $CONF.domain_quota===YES}<td>{$PALANG.pAdminList_domain_quota}</td>{/if}
</tr> </tr>
{foreach from=$domain_properties item=domain} {foreach from=$domain_properties item=domain}
{#tr_hilightoff#} {#tr_hilightoff#}
@ -23,6 +24,7 @@
<td>{$domain.alias_count} / {$domain.aliases}</td> <td>{$domain.alias_count} / {$domain.aliases}</td>
<td>{$domain.mailbox_count} / {$domain.mailboxes}</td> <td>{$domain.mailbox_count} / {$domain.mailboxes}</td>
{if $CONF.quota===YES}<td>{$domain.maxquota}</td>{/if} {if $CONF.quota===YES}<td>{$domain.maxquota}</td>{/if}
{if $CONF.domain_quota===YES}<td>{$domain.total_quota} / {$domain.quota}</td>{/if}
</tr> </tr>
{/foreach} {/foreach}
</table> </table>

Loading…
Cancel
Save