mail/postfix: merge version 0.3 from master

This commit is contained in:
Franco Fichtner 2017-12-19 07:11:05 +01:00
parent eb0eb24f94
commit 4def6c2214
22 changed files with 928 additions and 65 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

@ -58,6 +58,8 @@ class ServiceController extends ApiControllerBase
public function startAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$backend = new Backend();
$response = $backend->configdRun('postfix start');
return array("response" => $response);
@ -73,6 +75,8 @@ class ServiceController extends ApiControllerBase
public function stopAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$backend = new Backend();
$response = $backend->configdRun("postfix stop");
return array("response" => $response);
@ -88,6 +92,8 @@ class ServiceController extends ApiControllerBase
public function restartAction()
{
if ($this->request->isPost()) {
// close session for long running action
$this->sessionClose();
$backend = new Backend();
$response = $backend->configdRun("postfix restart");
return array("response" => $response);
@ -121,7 +127,6 @@ class ServiceController extends ApiControllerBase
$status = "unkown";
}
return array("status" => $status);
}

View file

@ -1,25 +1,30 @@
<?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.
*/
* 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;
@ -27,7 +32,6 @@ class DomainController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
$this->view->title = gettext("Postfix Domains");
$this->view->formDialogEditPostfixDomain = $this->getForm("dialogEditPostfixDomain");
$this->view->pick('OPNsense/Postfix/domain');
}

View file

@ -1,29 +1,30 @@
<?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.
*/
* 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;
@ -31,7 +32,6 @@ class GeneralController extends \OPNsense\Base\IndexController
{
public function indexAction()
{
$this->view->title = gettext("Postfix Settings");
$this->view->generalForm = $this->getForm("general");
$this->view->antispamForm = $this->getForm("antispam");
$this->view->pick('OPNsense/Postfix/general');

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

@ -34,21 +34,21 @@ POSSIBILITY OF SUCH DAMAGE.
<div id="general" class="tab-pane fade in active">
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_general_settings'])}}
<hr />
<div class="col-md-12">
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct_progress" class=""></i></button>
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
</div>
</div>
</div>
<div id="antispam" class="tab-pane fade in">
<div class="content-box" style="padding-bottom: 1.5em;">
<div class="alert alert-warning" role="alert" id="missing_rspamd" style="display:none;min-height:65px;">
<div class="alert alert-warning" role="alert" id="missing_rspamd" style="display:none;min-height:65px;">
<div style="margin-top: 8px;">{{ lang._('No Rspamd plugin found, please install and come back.')}}</div>
</div>
{{ partial("layout_partials/base_form",['fields':antispamForm,'id':'frm_antispam_settings'])}}
<hr />
<div class="col-md-12">
<button class="btn btn-primary" id="saveAct2" type="button"><b>{{ lang._('Save') }}</b><i id="saveAct2_progress" class=""></i></button>
<hr />
<button class="btn btn-primary" id="saveAct2" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct2_progress"></i></button>
</div>
</div>
</div>
@ -68,7 +68,7 @@ POSSIBILITY OF SUCH DAMAGE.
// check if Rspamd plugin is installed
ajaxCall(url="/api/postfix/service/checkrspamd", sendData={}, callback=function(data,status) {
if (data == "0") {
if (data == "0") {
$('#missing_rspamd').show();
}
});
@ -76,7 +76,7 @@ POSSIBILITY OF SUCH DAMAGE.
// link save button to API set action
$("#saveAct").click(function () {
saveFormToEndpoint(url="/api/postfix/general/set", formid='frm_general_settings',callback_ok=function () {
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/postfix/service/reconfigure", sendData={}, callback=function (data,status) {
ajaxCall(url="/api/postfix/service/status", sendData={}, callback=function (data,status) {
updateServiceStatusUI(data['status']);
@ -87,12 +87,12 @@ POSSIBILITY OF SUCH DAMAGE.
});
$("#saveAct2").click(function(){
saveFormToEndpoint(url="/api/postfix/antispam/set", formid='frm_antispam_settings',callback_ok=function(){
$("#saveAct2_progress").addClass("fa fa-spinner fa-pulse");
$("#saveAct2_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/postfix/service/reconfigure", sendData={}, callback=function(data,status) {
ajaxCall(url="/api/postfix/service/status", sendData={}, callback=function(data,status) {
updateServiceStatusUI(data['status']);
});
$("#saveAct2_progress").removeClass("fa fa-spinner fa-pulse");
$("#saveAct2_progress").removeClass("fa fa-spinner fa-pulse");
});
});
});

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 %}