mail/postfix: added sender / recipient access maps (#438)

* Create SenderController.php

* Create RecipientController.php

* Create SenderController.php

* Create RecipientController.php

* Create dialogEditPostfixSender.xml

* Create dialogEditPostfixRecipient.xml

* Update dialogEditPostfixSender.xml

* Create Sender.php

* Create Recipient.php

* Create Sender.xml

* Create Recipient.xml

* Update Menu.xml

* Create sender.volt

* Create recipient.volt

* Update Sender.xml

* Update Recipient.xml

* Update General.xml

* Update recipient_access

* Update sender_access

* Update Menu.xml

* Update Makefile

* Update RecipientController.php

* Update SenderController.php

* Update recipient_access

* Update sender_access

* Update RecipientController.php

* Update SenderController.php

* Update recipient_access

* Update sender_access

* Update main.cf

* Update RecipientController.php

* Update SenderController.php

* Update Menu.xml
This commit is contained in:
Michael 2017-12-17 23:19:35 +01:00 committed by Franco Fichtner
parent 64c8f55cdb
commit ac5ca7ffb8
18 changed files with 863 additions and 9 deletions

View file

@ -1,5 +1,5 @@
PLUGIN_NAME= postfix
PLUGIN_VERSION= 0.2
PLUGIN_VERSION= 0.3
PLUGIN_COMMENT= SMTP mail relay
PLUGIN_DEPENDS= postfix-sasl
PLUGIN_MAINTAINER= m.muenz@gmail.com

View file

@ -0,0 +1,205 @@
<?php
/**
* Copyright (C) 2015 - 2017 Deciso B.V.
* Copyright (C) 2017 Michael Muenz
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OPNsense\Postfix\Api;
use \OPNsense\Postfix\Recipient;
use \OPNsense\Core\Config;
use \OPNsense\Base\ApiMutableModelControllerBase;
use \OPNsense\Base\UIModelGrid;
class RecipientController extends ApiMutableModelControllerBase
{
static protected $internalModelName = 'Recipient';
static protected $internalModelClass = '\OPNsense\Postfix\Recipient';
public function getAction()
{
// define list of configurable settings
$result = array();
if ($this->request->isGet()) {
$mdlRecipient = new Recipient();
$result['recipient'] = $mdlRecipient->getNodes();
}
return $result;
}
public function setAction()
{
$result = array("result"=>"failed");
if ($this->request->isPost()) {
// load model and update with provided data
$mdlRecipient = new Recipient();
$mdlRecipient->setNodes($this->request->getPost("recipient"));
// perform validation
$valMsgs = $mdlRecipient->performValidation();
foreach ($valMsgs as $field => $msg) {
if (!array_key_exists("validations", $result)) {
$result["validations"] = array();
}
$result["validations"]["recipient.".$msg->getField()] = $msg->getMessage();
}
// serialize model to config and save
if ($valMsgs->count() == 0) {
$mdlRecipient->serializeToConfig();
Config::getInstance()->save();
$result["result"] = "saved";
}
}
return $result;
}
public function searchRecipientAction()
{
$this->sessionClose();
$mdlRecipient = $this->getModel();
$grid = new UIModelGrid($mdlRecipient->recipients->recipient);
return $grid->fetchBindRequest(
$this->request,
array("enabled", "address", "action" )
);
}
public function getRecipientAction($uuid = null)
{
$mdlRecipient = $this->getModel();
if ($uuid != null) {
$node = $mdlRecipient->getNodeByReference('recipients.recipient.' . $uuid);
if ($node != null) {
// return node
return array("recipient" => $node->getNodes());
}
} else {
$node = $mdlRecipient->recipients->recipient->add();
return array("recipient" => $node->getNodes());
}
return array();
}
public function addRecipientAction()
{
$result = array("result" => "failed");
if ($this->request->isPost() && $this->request->hasPost("recipient")) {
$result = array("result" => "failed", "validations" => array());
$mdlRecipient = $this->getModel();
$node = $mdlRecipient->recipients->recipient->Add();
$node->setNodes($this->request->getPost("recipient"));
$valMsgs = $mdlRecipient->performValidation();
foreach ($valMsgs as $field => $msg) {
$fieldnm = str_replace($node->__reference, "recipient", $msg->getField());
$result["validations"][$fieldnm] = $msg->getMessage();
}
if (count($result['validations']) == 0) {
unset($result['validations']);
// save config if validated correctly
$mdlRecipient->serializeToConfig();
Config::getInstance()->save();
unset($result['validations']);
$result["result"] = "saved";
}
}
return $result;
}
public function delRecipientAction($uuid)
{
$result = array("result" => "failed");
if ($this->request->isPost()) {
$mdlRecipient = $this->getModel();
if ($uuid != null) {
if ($mdlRecipient->recipients->recipient->del($uuid)) {
$mdlRecipient->serializeToConfig();
Config::getInstance()->save();
$result['result'] = 'deleted';
} else {
$result['result'] = 'not found';
}
}
}
return $result;
}
public function setRecipientAction($uuid)
{
if ($this->request->isPost() && $this->request->hasPost("recipient")) {
$mdlSetting = $this->getModel();
if ($uuid != null) {
$node = $mdlSetting->getNodeByReference('recipients.recipient.' . $uuid);
if ($node != null) {
$result = array("result" => "failed", "validations" => array());
$recipientInfo = $this->request->getPost("recipient");
$node->setNodes($recipientInfo);
$valMsgs = $mdlSetting->performValidation();
foreach ($valMsgs as $field => $msg) {
$fieldnm = str_replace($node->__reference, "recipient", $msg->getField());
$result["validations"][$fieldnm] = $msg->getMessage();
}
if (count($result['validations']) == 0) {
// save config if validated correctly
$mdlSetting->serializeToConfig();
Config::getInstance()->save();
$result = array("result" => "saved");
}
return $result;
}
}
}
return array("result" => "failed");
}
public function toggle_handler($uuid, $elements, $element)
{
$result = array("result" => "failed");
if ($this->request->isPost()) {
$mdlSetting = $this->getModel();
if ($uuid != null) {
$node = $mdlSetting->getNodeByReference($elements . '.'. $element .'.' . $uuid);
if ($node != null) {
if ($node->enabled->__toString() == "1") {
$result['result'] = "Disabled";
$node->enabled = "0";
} else {
$result['result'] = "Enabled";
$node->enabled = "1";
}
// if item has toggled, serialize to config and save
$mdlSetting->serializeToConfig();
Config::getInstance()->save();
}
}
}
return $result;
}
public function toggleRecipientAction($uuid)
{
return $this->toggle_handler($uuid, 'recipients', 'recipient');
}
}

View file

@ -0,0 +1,205 @@
<?php
/**
* Copyright (C) 2015 - 2017 Deciso B.V.
* Copyright (C) 2017 Michael Muenz
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
namespace OPNsense\Postfix\Api;
use \OPNsense\Postfix\Sender;
use \OPNsense\Core\Config;
use \OPNsense\Base\ApiMutableModelControllerBase;
use \OPNsense\Base\UIModelGrid;
class SenderController extends ApiMutableModelControllerBase
{
static protected $internalModelName = 'Sender';
static protected $internalModelClass = '\OPNsense\Postfix\Sender';
public function getAction()
{
// define list of configurable settings
$result = array();
if ($this->request->isGet()) {
$mdlSender = new Sender();
$result['sender'] = $mdlSender->getNodes();
}
return $result;
}
public function setAction()
{
$result = array("result"=>"failed");
if ($this->request->isPost()) {
// load model and update with provided data
$mdlSender = new Sender();
$mdlSender->setNodes($this->request->getPost("sender"));
// perform validation
$valMsgs = $mdlSender->performValidation();
foreach ($valMsgs as $field => $msg) {
if (!array_key_exists("validations", $result)) {
$result["validations"] = array();
}
$result["validations"]["sender.".$msg->getField()] = $msg->getMessage();
}
// serialize model to config and save
if ($valMsgs->count() == 0) {
$mdlSender->serializeToConfig();
Config::getInstance()->save();
$result["result"] = "saved";
}
}
return $result;
}
public function searchSenderAction()
{
$this->sessionClose();
$mdlSender = $this->getModel();
$grid = new UIModelGrid($mdlSender->senders->sender);
return $grid->fetchBindRequest(
$this->request,
array("enabled", "address", "action" )
);
}
public function getSenderAction($uuid = null)
{
$mdlSender = $this->getModel();
if ($uuid != null) {
$node = $mdlSender->getNodeByReference('senders.sender.' . $uuid);
if ($node != null) {
// return node
return array("sender" => $node->getNodes());
}
} else {
$node = $mdlSender->senders->sender->add();
return array("sender" => $node->getNodes());
}
return array();
}
public function addSenderAction()
{
$result = array("result" => "failed");
if ($this->request->isPost() && $this->request->hasPost("sender")) {
$result = array("result" => "failed", "validations" => array());
$mdlSender = $this->getModel();
$node = $mdlSender->senders->sender->Add();
$node->setNodes($this->request->getPost("sender"));
$valMsgs = $mdlSender->performValidation();
foreach ($valMsgs as $field => $msg) {
$fieldnm = str_replace($node->__reference, "sender", $msg->getField());
$result["validations"][$fieldnm] = $msg->getMessage();
}
if (count($result['validations']) == 0) {
unset($result['validations']);
// save config if validated correctly
$mdlSender->serializeToConfig();
Config::getInstance()->save();
unset($result['validations']);
$result["result"] = "saved";
}
}
return $result;
}
public function delSenderAction($uuid)
{
$result = array("result" => "failed");
if ($this->request->isPost()) {
$mdlSender = $this->getModel();
if ($uuid != null) {
if ($mdlSender->senders->sender->del($uuid)) {
$mdlSender->serializeToConfig();
Config::getInstance()->save();
$result['result'] = 'deleted';
} else {
$result['result'] = 'not found';
}
}
}
return $result;
}
public function setSenderAction($uuid)
{
if ($this->request->isPost() && $this->request->hasPost("sender")) {
$mdlSetting = $this->getModel();
if ($uuid != null) {
$node = $mdlSetting->getNodeByReference('senders.sender.' . $uuid);
if ($node != null) {
$result = array("result" => "failed", "validations" => array());
$senderInfo = $this->request->getPost("sender");
$node->setNodes($senderInfo);
$valMsgs = $mdlSetting->performValidation();
foreach ($valMsgs as $field => $msg) {
$fieldnm = str_replace($node->__reference, "sender", $msg->getField());
$result["validations"][$fieldnm] = $msg->getMessage();
}
if (count($result['validations']) == 0) {
// save config if validated correctly
$mdlSetting->serializeToConfig();
Config::getInstance()->save();
$result = array("result" => "saved");
}
return $result;
}
}
}
return array("result" => "failed");
}
public function toggle_handler($uuid, $elements, $element)
{
$result = array("result" => "failed");
if ($this->request->isPost()) {
$mdlSetting = $this->getModel();
if ($uuid != null) {
$node = $mdlSetting->getNodeByReference($elements . '.'. $element .'.' . $uuid);
if ($node != null) {
if ($node->enabled->__toString() == "1") {
$result['result'] = "Disabled";
$node->enabled = "0";
} else {
$result['result'] = "Enabled";
$node->enabled = "1";
}
// if item has toggled, serialize to config and save
$mdlSetting->serializeToConfig();
Config::getInstance()->save();
}
}
}
return $result;
}
public function toggleSenderAction($uuid)
{
return $this->toggle_handler($uuid, 'senders', 'sender');
}
}

View file

@ -0,0 +1,33 @@
<?php
/*
Copyright (C) 2017 Michael Muenz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\Postfix;
class RecipientController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
$this->view->formDialogEditPostfixRecipient = $this->getForm("dialogEditPostfixRecipient");
$this->view->pick('OPNsense/Postfix/recipient');
}
}

View file

@ -0,0 +1,33 @@
<?php
/*
Copyright (C) 2017 Michael Muenz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
namespace OPNsense\Postfix;
class SenderController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
$this->view->formDialogEditPostfixSender = $this->getForm("dialogEditPostfixSender");
$this->view->pick('OPNsense/Postfix/sender');
}
}

View file

@ -0,0 +1,20 @@
<form>
<field>
<id>recipient.enabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help>This will enable or disable the recipient rule in this entry.</help>
</field>
<field>
<id>recipient.address</id>
<label>Sender Address</label>
<type>text</type>
<help>Set the recipient address to match.</help>
</field>
<field>
<id>recipient.action</id>
<label>Action</label>
<type>dropdown</type>
<help>Set the action for this address.</help>
</field>
</form>

View file

@ -0,0 +1,20 @@
<form>
<field>
<id>sender.enabled</id>
<label>Enabled</label>
<type>checkbox</type>
<help>This will enable or disable the sender address to match for.</help>
</field>
<field>
<id>sender.address</id>
<label>Sender Address</label>
<type>text</type>
<help>Set the sender address to match.</help>
</field>
<field>
<id>sender.action</id>
<label>Action</label>
<type>dropdown</type>
<help>Set the action for this address.</help>
</field>
</form>

View file

@ -60,14 +60,10 @@
<encrypt>encrypt</encrypt>
</OptionValues>
</smtpclient_security>
<check_recipient_access type="ArrayField">
</check_recipient_access>
<reject_unauth_pipelining type="BooleanField">
<default>1</default>
<Required>Y</Required>
</reject_unauth_pipelining>
<check_sender_access type="ArrayField">
</check_sender_access>
<reject_unknown_sender_domain type="BooleanField">
<default>1</default>
<Required>Y</Required>

View file

@ -3,6 +3,8 @@
<Postfix cssClass="fa fa-envelope fa-fw">
<General url="/ui/postfix/general/index" order="10"/>
<Domains url="/ui/postfix/domain/index" order="20"/>
<Recipients url="/ui/postfix/recipient/index" order="30"/>
<Senders url="/ui/postfix/sender/index" order="40"/>
</Postfix>
</Services>
</menu>

View file

@ -0,0 +1,30 @@
<?php
namespace OPNsense\Postfix;
use OPNsense\Base\BaseModel;
/*
Copyright (C) 2017 Michael Muenz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
class Recipient extends BaseModel
{
}

View file

@ -0,0 +1,25 @@
<model>
<mount>//OPNsense/postfix/recipient</mount>
<description>Postfix recipient configuration</description>
<version>1.0.0</version>
<items>
<recipients>
<recipient type="ArrayField">
<enabled type="BooleanField">
<default>1</default>
<Required>Y</Required>
</enabled>
<address type="TextField">
<Required>Y</Required>
</address>
<action type="OptionField">
<Required>Y</Required>
<OptionValues>
<OK>OK</OK>
<REJECT>REJECT</REJECT>
</OptionValues>
</action>
</recipient>
</recipients>
</items>
</model>

View file

@ -0,0 +1,30 @@
<?php
namespace OPNsense\Postfix;
use OPNsense\Base\BaseModel;
/*
Copyright (C) 2017 Michael Muenz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
class Sender extends BaseModel
{
}

View file

@ -0,0 +1,25 @@
<model>
<mount>//OPNsense/postfix/sender</mount>
<description>Postfix sender configuration</description>
<version>1.0.0</version>
<items>
<senders>
<sender type="ArrayField">
<enabled type="BooleanField">
<default>1</default>
<Required>Y</Required>
</enabled>
<address type="TextField">
<Required>Y</Required>
</address>
<action type="OptionField">
<Required>Y</Required>
<OptionValues>
<OK>OK</OK>
<REJECT>REJECT</REJECT>
</OptionValues>
</action>
</sender>
</senders>
</items>
</model>

View file

@ -0,0 +1,110 @@
{#
OPNsense® is Copyright © 2014 2017 by Deciso B.V.
Copyright (C) 2017 Michael Muenz
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
#}
<script type="text/javascript">
$( document ).ready(function() {
/*************************************************************************************************************
* link grid actions
*************************************************************************************************************/
$("#grid-recipients").UIBootgrid(
{ 'search':'/api/postfix/recipient/searchRecipient',
'get':'/api/postfix/recipient/getRecipient/',
'set':'/api/postfix/recipient/setRecipient/',
'add':'/api/postfix/recipient/addRecipient/',
'del':'/api/postfix/recipient/delRecipient/',
'toggle':'/api/postfix/recipient/toggleRecipient/'
}
);
/*************************************************************************************************************
* Commands
*************************************************************************************************************/
/**
* Reconfigure
*/
$("#reconfigureAct").click(function(){
$("#reconfigureAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/postfix/service/reconfigure", sendData={}, callback=function(data,status) {
// when done, disable progress animation.
$("#reconfigureAct_progress").removeClass("fa fa-spinner fa-pulse");
if (status != "success" || data['status'] != 'ok') {
BootstrapDialog.show({
type: BootstrapDialog.TYPE_WARNING,
title: "{{ lang._('Error reconfiguring Postfix') }}",
message: data['status'],
draggable: true
});
} else {
ajaxCall(url="/api/postfix/service/reconfigure", sendData={});
}
});
});
});
</script>
<div class="tab-content content-box tab-content">
<div id="recipients" class="tab-pane fade in active">
<!-- tab page "recipients" -->
<table id="grid-recipients" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="dialogEditPostfixRecipient">
<thead>
<tr>
<th data-column-id="enabled" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
<th data-column-id="address" data-type="string" data-visible="true">{{ lang._('Address') }}</th>
<th data-column-id="action" data-type="string" data-visible="true">{{ lang._('Action') }}</th>
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
<th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th> </tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
<div class="col-md-12">
<hr/>
<button class="btn btn-primary" id="reconfigureAct" type="button"><b>{{ lang._('Apply') }}</b> <i id="reconfigureAct_progress" class=""></i></button>
<br/><br/>
</div>
</div>
{{ partial("layout_partials/base_dialog",['fields':formDialogEditPostfixRecipient,'id':'dialogEditPostfixRecipient','label':lang._('Edit Recipient')])}}

View file

@ -0,0 +1,110 @@
{#
OPNsense® is Copyright © 2014 2017 by Deciso B.V.
Copyright (C) 2017 Michael Muenz
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
#}
<script type="text/javascript">
$( document ).ready(function() {
/*************************************************************************************************************
* link grid actions
*************************************************************************************************************/
$("#grid-senders").UIBootgrid(
{ 'search':'/api/postfix/sender/searchSender',
'get':'/api/postfix/sender/getSender/',
'set':'/api/postfix/sender/setSender/',
'add':'/api/postfix/sender/addSender/',
'del':'/api/postfix/sender/delSender/',
'toggle':'/api/postfix/sender/toggleSender/'
}
);
/*************************************************************************************************************
* Commands
*************************************************************************************************************/
/**
* Reconfigure
*/
$("#reconfigureAct").click(function(){
$("#reconfigureAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/postfix/service/reconfigure", sendData={}, callback=function(data,status) {
// when done, disable progress animation.
$("#reconfigureAct_progress").removeClass("fa fa-spinner fa-pulse");
if (status != "success" || data['status'] != 'ok') {
BootstrapDialog.show({
type: BootstrapDialog.TYPE_WARNING,
title: "{{ lang._('Error reconfiguring Postfix') }}",
message: data['status'],
draggable: true
});
} else {
ajaxCall(url="/api/postfix/service/reconfigure", sendData={});
}
});
});
});
</script>
<div class="tab-content content-box tab-content">
<div id="senders" class="tab-pane fade in active">
<!-- tab page "senders" -->
<table id="grid-senders" class="table table-condensed table-hover table-striped table-responsive" data-editDialog="dialogEditPostfixSender">
<thead>
<tr>
<th data-column-id="enabled" data-type="string" data-formatter="rowtoggle">{{ lang._('Enabled') }}</th>
<th data-column-id="address" data-type="string" data-visible="true">{{ lang._('Address') }}</th>
<th data-column-id="action" data-type="string" data-visible="true">{{ lang._('Action') }}</th>
<th data-column-id="uuid" data-type="string" data-identifier="true" data-visible="false">{{ lang._('ID') }}</th>
<th data-column-id="commands" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th> </tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<td></td>
<td>
<button data-action="add" type="button" class="btn btn-xs btn-default"><span class="fa fa-plus"></span></button>
<button data-action="deleteSelected" type="button" class="btn btn-xs btn-default"><span class="fa fa-trash-o"></span></button>
</td>
</tr>
</tfoot>
</table>
</div>
<div class="col-md-12">
<hr/>
<button class="btn btn-primary" id="reconfigureAct" type="button"><b>{{ lang._('Apply') }}</b> <i id="reconfigureAct_progress" class=""></i></button>
<br/><br/>
</div>
</div>
{{ partial("layout_partials/base_dialog",['fields':formDialogEditPostfixSender,'id':'dialogEditPostfixSender','label':lang._('Edit Sender')])}}

View file

@ -98,13 +98,13 @@ milter_default_action = accept
{# Sender Restrictions #}
{% set smtpd_recipient_restrictions=[] %}
{% if helpers.exists('OPNsense.postfix.general.check_recipient_access') %}
{% if helpers.exists('OPNsense.postfix.recipient.recipients.recipient') %}
{% do smtpd_recipient_restrictions.append('check_recipient_access hash:/usr/local/etc/postfix/recipient_access') %}
{% endif %}
{% if helpers.exists('OPNsense.postfix.general.reject_unauth_pipelining') and OPNsense.postfix.general.reject_unauth_pipelining == '1' %}
{% do smtpd_recipient_restrictions.append('reject_unauth_pipelining') %}
{% endif %}
{% if helpers.exists('OPNsense.postfix.general.check_sender_access') %}
{% if helpers.exists('OPNsense.postfix.sender.senders.sender') %}
{% do smtpd_recipient_restrictions.append('check_sender_access hash:/usr/local/etc/postfix/sender_access') %}
{% endif %}
{% if helpers.exists('OPNsense.postfix.general.reject_unknown_sender_domain') and OPNsense.postfix.general.reject_unknown_sender_domain == '1' %}

View file

@ -1,4 +1,9 @@
{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %}
{% if helpers.exists('OPNsense.postfix.general.check_recipient_access') %}
{% if helpers.exists('OPNsense.postfix.recipient.recipients.recipient') %}
{% for recipient_list in helpers.toList('OPNsense.postfix.recipient.recipients.recipient') %}
{% if recipient_list.enabled == '1' %}
{{ recipient_list.address }} {{ recipient_list.action }}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}

View file

@ -1,4 +1,9 @@
{% if helpers.exists('OPNsense.postfix.general.enabled') and OPNsense.postfix.general.enabled == '1' %}
{% if helpers.exists('OPNsense.postfix.general.check_recipient_access') %}
{% if helpers.exists('OPNsense.postfix.sender.senders.sender') %}
{% for sender_list in helpers.toList('OPNsense.postfix.sender.senders.sender') %}
{% if sender_list.enabled == '1' %}
{{ sender_list.address }} {{ sender_list.action }}
{% endif %}
{% endfor %}
{% endif %}
{% endif %}