Commit ba26ef8e authored by Ted Trask's avatar Ted Trask

Initial cut - but pretty close to complete.

parents
APP_NAME=freeswitch-vmail
PACKAGE=acf-$(APP_NAME)
VERSION=0.0.1
APP_DIST=\
vmail* \
template* \
LIB_DIST=authenticator-freeswitch-vmail.lua
EXTRA_DIST=README Makefile config.mk
DISTFILES=$(APP_DIST) $(LIB_DIST) $(EXTRA_DIST)
TAR=tar
P=$(PACKAGE)-$(VERSION)
tarball=$(P).tar.bz2
install_dir=$(DESTDIR)/$(appdir)/$(APP_NAME)
all:
clean:
rm -rf $(tarball) $(P)
dist: $(tarball)
install:
mkdir -p "$(install_dir)"
cp -a $(APP_DIST) "$(install_dir)"
mkdir -p "$(acflibdir)"
cp -a $(LIB_DIST) "$(acflibdir)"
$(tarball): $(DISTFILES)
rm -rf $(P)
mkdir -p $(P)
cp -a $(DISTFILES) $(P)
$(TAR) -jcf $@ $(P)
rm -rf $(P)
# target that creates a tar package, unpacks is and install from package
dist-install: $(tarball)
$(TAR) -jxf $(tarball)
$(MAKE) -C $(P) install DESTDIR=$(DESTDIR)
rm -rf $(P)
include config.mk
.PHONY: all clean dist install dist-install
acf-freeswitch-vmail is a web interface that works with Freeswitch to implement a single-domain voicemail server. Since it uses mod_xml_curl and mod_event_socket, these must be configured properly in Freeswitch for acf-freeswitch-mail to work.
Be sure to load both modules in autoload_configs/modules.conf.xml
The following content can be used in autoload_configs/xml_curl.conf.xml:
<configuration name="xml_curl.conf" description="cURL XML Gateway">
<bindings>
<binding name="voicemaildialplan">
<param name="gateway-url" value="https://127.0.0.1/cgi-bin/acf/freeswitch-vmail/vmail/processdialplanxml" bindings="dialplan"/>
</binding>
<binding name="voicemaildirectory">
<param name="gateway-url" value="https://127.0.0.1/cgi-bin/acf/freeswitch-vmail/vmail/processdirectoryxml" bindings="directory"/>
</binding>
</bindings>
</configuration>
-- Copy of authenticator-plaintext, plus added authentication from voicemail DB
module (..., package.seeall)
require("md5")
a = require("authenticator-plaintext")
list_fields = function(self, tabl)
result = a.list_fields(self, tabl)
return result
end
read_field = function(self, tabl, field)
result = a.read_field(self, tabl, field)
if tabl == authenticator.usertable and field == "" then
-- authenticator is reading all users
local vmcontroller = self:new("freeswitch-vmail/vmail")
local users = vmcontroller:listusers()
for i,val in ipairs(users.value) do
local settings = vmcontroller.model.get_usersettings(val.username)
local string = md5.sumhexa(settings.value["vm-password"].value)..":Voicemail User:/freeswitch-vmail/vmail/USER"
result[#result+1] = { id=settings.value.username.value, entry=string }
end
vmcontroller:destroy()
end
return result
end
delete_field = function(self, tabl, field)
result = a.delete_field(self, tabl, field)
return result
end
write_entry = function(self, tabl, field, id, entry)
result = a.write_entry(self, tabl, field, id, entry)
return result
end
read_entry = function(self, tabl, field, id)
result = a.read_entry(self, tabl, field, id)
return result
end
delete_entry = function (self, tabl, field, id)
result = a.delete_entry(self, tabl, field, id)
return result
end
prefix=/usr
datadir=${prefix}/share
sysconfdir=${prefix}/etc
localstatedir=${prefix}/var
acfdir=${datadir}/acf
wwwdir=${acfdir}/www
cgibindir=${acfdir}/cgi-bin
appdir=${acfdir}/app
acflibdir=${acfdir}/lib
sessionsdir=${localstatedir}/lib/acf/sessions
<% local viewtable, viewlibrary, pageinfo, session = ... %>
<% if viewtable and not viewtable.errtxt then %>
Content-Type: Content Type: text/xml
<document type="freeswitch/xml">
<section name="dialplan">
<context name="default">
<extension name="Voicemail">
<condition expression="(.*)" field="destination_number">
<action application="answer" />
<action application="sleep" data="1000" />
<action application="voicemail" data="default <%= viewtable.value.domain.value %> $1" />
</condition>
</extension>
</context>
</section>
</document>
<% end %>
<% local viewtable, viewlibrary, pageinfo, session = ... %>
<% if viewtable and not viewtable.errtxt then %>
Content-Type: Content Type: text/xml
<document type="freeswitch/xml">
<section name="directory">
<domain name="<%= viewtable.value.domain.value %>">
<params>
<param name="dial-string" value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}" />
</params>
<groups>
<group name="default">
<users>
<user id="<%= viewtable.value.username.value %>">
<params>
<param name="vm-enable" value="true>" />
<%
local ignore = {username=true, fullname=true, domain=true, ["vm-password-confirm"]=true }
for name,val in pairs(viewtable.value) do
if not ignore[name] then %>
<param name="<%= name %>" value="<%= tostring(val.value) %>" />
<% end %>
<% end %>
</params>
</user>
</users>
</group>
</groups>
</domain>
</section>
</document>
<% end %>
module (..., package.seeall)
require("controllerfunctions")
default_action = "listmessages"
listusers = function( self )
return self.model.list_users()
end
editusers = function( self )
return self.model.list_users()
end
deleteuser = function( self )
return self:redirect_to_referrer(self.model.delete_user(self.clientdata.username))
end
listmessages = function( self )
return self.model.list_messages(self.clientdata.username)
end
listmymessages = function( self )
return self.model.list_messages(self.sessiondata.userinfo.userid)
end
downloadmessage = function( self )
self.conf.viewtype = "stream"
return self.model.get_message(self.clientdata.message)
end
downloadmymessage = function( self )
self.conf.viewtype = "stream"
return self.model.get_message(self.clientdata.message, self.sessiondata.userinfo.userid)
end
deletemessage = function( self )
return self:redirect_to_referrer(self.model.delete_message(self.clientdata.message))
end
deletemymessage = function( self )
return self:redirect_to_referrer(self.model.delete_message(self.clientdata.message, self.sessiondata.userinfo.userid))
end
forwardmessage = function( self )
return self:redirect_to_referrer(self.model.forward_message(self.clientdata.message, self.clientdata.newuser))
end
forwardmymessage = function( self )
return self:redirect_to_referrer(self.model.forward_message(self.clientdata.message, self.clientdata.newuser, self.sessiondata.userinfo.userid))
end
emailmessage = function( self )
return self:redirect_to_referrer(self.model.email_message(self.clientdata.message, self.clientdata.address))
end
emailmymessage = function( self )
return self:redirect_to_referrer(self.model.email_message(self.clientdata.message, self.clientdata.address, self.sessiondata.userinfo.userid))
end
editusersettings = function( self )
return controllerfunctions.handle_form(self, function() return self.model.get_usersettings(self.clientdata.username) end, self.model.update_usersettings, self.clientdata, "Save", "Edit Settings", "Settings Saved")
end
editmyusersettings = function( self )
return controllerfunctions.handle_form(self, function() return self.model.get_usersettings(self.sessiondata.userinfo.userid) end, self.model.update_usersettings, self.clientdata, "Save", "Edit Settings", "Settings Saved")
end
createuser = function( self )
return controllerfunctions.handle_form(self, function() return self.model.get_usersettings() end, self.model.create_usersettings, self.clientdata, "Create", "Create User", "User Created")
end
processdialplanxml = function( self )
self.conf.viewtype = "xml"
return self.model.process_dialplan_xml_request(self.clientdata)
end
processdirectoryxml = function( self )
self.conf.viewtype = "xml"
return self.model.process_directory_xml_request(self.clientdata)
end
editconfig = function( self )
return controllerfunctions.handle_form(self, self.model.get_config, self.model.update_config, self.clientdata, "Save", "Update Config", "Config Saved")
end
vmail-editusersettings-html.lsp
\ No newline at end of file
../form-html.lsp
\ No newline at end of file
vmail-editusersettings-html.lsp
\ No newline at end of file
vmail-listusers-html.lsp
\ No newline at end of file
<% local form, viewlibrary, page_info = ...
require("viewfunctions")
%>
<H1>Settings for <%= html.html_escape(form.value.fullname.value) %> (<%= html.html_escape(form.value.username.value) %>)</H1>
<%
form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action
if page_info.action ~= "createuser" then
form.value.username.readonly = true
end
form.value["vm-password"].type = "password"
form.value["vm-password-confirm"].type = "password"
local order = {"username", "fullname", "vm-password", "vm-password-confirm", "vm-mailto", "vm-email-all-messages", "vm-attach-file", "vm-keep-local-after-email", "vm-notify-mailto", "vm-notify-email-all-messages", "vm-say-caller-id", "vm-say-envelope"}
displayform(form, order)
%>
<% local view, viewlibrary, page_info, session = ...
require("viewfunctions")
%>
<% -- Pregenerate the list of users
if viewlibrary.check_permission("listusers") and (viewlibrary.check_permission("forwardmessage") or viewlibrary.check_permission("forwardmymessage")) then
local users = viewlibrary.dispatch_component("listusers", nil, true)
options = {}
for i,u in ipairs(users.value) do
if u.username ~= session.userinfo.userid then
options[#options+1] = '<option value="'..html.html_escape(u.username)..'">'..html.html_escape(u.fullname)..' ('..html.html_escape(u.username)..')</option>'
end
end
options = table.concat(options)
end
%>
<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery-latest.js"></script>
<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery.tablesorter.js"></script>
<script type="text/javascript">
function PlayMessage() {
$(".temporaryplayer").remove();
$(this).parent().parent().after("<tr class='temporaryplayer'><td colspan='8'><embed width='100%' height='25px' marginheight='0' marginwidth='0' frameborder='0' scrolling='no' autostart='false' autoplay='false' loop='false' src='" + $(this).attr("href") + "'></embed></TD></TR>");
return false;
}
function HandleMulti() {
var messages = [];
$(".multicheck:checked").each(function(){
messages[messages.length] = this.value;
});
$(this).parent().find("[name='message']").attr("value", messages.join(","));
}
$(document).ready(function() {
$("#list").tablesorter({headers: {0:{sorter: false}, 1:{sorter: false}}});
$("#list").bind("sortStart",function() {
$(".temporaryplayer").remove();
});
$(".playmessage").click(PlayMessage);
<% if viewlibrary.check_permission("deletemessage") or viewlibrary.check_permission("deletemymessage") then %>
$("#multidelete").click(HandleMulti);
<% end %>
<% if viewlibrary.check_permission("forwardmessage") or viewlibrary.check_permission("forwardmymessage") then %>
$("#multiforward").click(HandleMulti);
<% end %>
<% if viewlibrary.check_permission("emailmessage") or viewlibrary.check_permission("emailmymessage") then %>
$("#multiemail").click(HandleMulti);
<% end %>
});
</script>
<% displaycommandresults({"deletemessage", "deletemymessage", "forwardmessage", "forwardmymessage", "emailmessage", "emailmymessage"}, session) %>
<h1>Messages</h1>
<DL>
<TABLE><TR><TD>
<% if viewlibrary.check_permission("deletemessage") or viewlibrary.check_permission("deletemymessage") then %>
<form id="multidelete" action="<%= html.html_escape(page_info.script..page_info.prefix..page_info.controller) %>/
<% if viewlibrary.check_permission("deletemessage") then io.write("deletemessage") else io.write("deletemymessage") end %>
" method="POST">
<input class="hidden" type="hidden" name="redir" value="<%= html.html_escape(page_info.orig_action) %>" >
<input class="hidden" type="hidden" name="message" value="" >
<input class="submit" type="submit" value="Delete">
</form>
<% end %>
<% if viewlibrary.check_permission("forwardmessage") or viewlibrary.check_permission("forwardmymessage") then %>
<form id="multiforward" action="<%= html.html_escape(page_info.script .. page_info.prefix .. page_info.controller) %>/
<% if viewlibrary.check_permission("forwardmessage") then io.write("forwardmessage") else io.write("forwardmymessage") end %>
" method="POST">
<input class="hidden" type="hidden" name="redir" value="<%= html.html_escape(page_info.orig_action) %>" >
<input class="hidden" type="hidden" name="message" value="" >
<select name="newuser"><%= (options or "") %></select>
<input class="submit" type="submit" value="Forward">
</form>
<% end %>
<% if viewlibrary.check_permission("emailmessage") or viewlibrary.check_permission("emailmymessage") then %>
<form id="multiemail" action="<%= html.html_escape(page_info.script .. page_info.prefix .. page_info.controller) %>/
<% if viewlibrary.check_permission("emailmessage") then io.write("emailmessage") else io.write("emailmymessage") end %>
" method="POST">
<input class="hidden" type="hidden" name="redir" value="<%= html.html_escape(page_info.orig_action) %>" >
<input class="hidden" type="hidden" name="message" value="" >
<input class="text" type="text" name="address" value="" >
<input class="submit" type="submit" value="E-mail">
</form>
<% end %>
</TD></TR></TABLE>
<TABLE id="list" class="tablesorter"><THEAD>
<TR style="background:#eee;font-weight:bold;">
<TH></TH>
<TH>Action</TH>
<TH>Date</TH>
<TH>Time</TH>
<TH>Caller ID</TH>
<TH>Priority</TH>
<TH>Orig Mailbox</Th>
<TH>Duration</TH>
</TR>
</THEAD><TBODY>
<% for k,v in ipairs( view.value ) do %>
<TR>
<TD><input type=checkbox class="multicheck" value="<%= html.html_escape(v.uuid) %>"></TD>
<TD>
<% if viewlibrary.check_permission("downloadmessage") then %>
<%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/downloadmessage?message="..v.uuid, label="Download "} %>
<%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/downloadmessage?message="..v.uuid, class="playmessage", label="Play "} %>
<% elseif viewlibrary.check_permission("downloadmymessage") then %>
<%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/downloadmymessage?message="..v.uuid, label="Download "} %>
<%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/downloadmymessage?message="..v.uuid, class="playmessage", label="Play "} %>
<% end %>
</TD>
<TD><%= html.html_escape(os.date("%x", v.created_epoch)) %></TD>
<TD><%= html.html_escape(os.date("%X", v.created_epoch)) %></TD>
<TD><%= html.html_escape(v.cid_number) %></TD>
<TD><%= html.html_escape(v.read_flags) %></TD>
<TD><%= html.html_escape(v.username) %></TD>
<TD><%= html.html_escape(v.message_len) %></TD>
</TR>
<% end %>
</TBODY>
</TABLE>
<% if view.errtxt then %>
<p class="error"><%= html.html_escape(view.errtxt) %></p>
<% end %>
<% if #view.value == 0 then %>
<p>No messages found</p>
<% end %>
</DL>
vmail-listmessages-html.lsp
\ No newline at end of file
<% local view, viewlibrary, page_info, session = ...
require("viewfunctions")
%>
<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery-latest.js"></script>
<script type="text/javascript" src="<%= html.html_escape(page_info.wwwprefix) %>/js/jquery.tablesorter.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#list").tablesorter({headers: {0:{sorter: false}}});
});
</script>
<% displaycommandresults({"createuser", "deleteuser", "editusersettings"}, session) %>
<h1>Messages</h1>
<DL><TABLE id="list" class="tablesorter"><THEAD>
<TR style="background:#eee;font-weight:bold;">
<TH>Action</TH>
<TH>Extension</TH>
<TH>Full Name</TH>
</TR>
</THEAD><TBODY>
<% for k,v in ipairs( view.value ) do %>
<TR>
<TD>
<% if viewlibrary.check_permission("editusersettings") then %>
<%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/editusersettings?username="..v.username, label="Edit "} %>
<% end %>
<% if viewlibrary.check_permission("deleteuser") then %>
<%= html.link{value=page_info.script..page_info.prefix..page_info.controller.."/deleteuser?username="..v.username, label="Delete "} %>
<% end %>
</TD>
<TD><%= html.html_escape(v.username) %></TD>
<TD><%= html.html_escape(v.fullname) %></TD>
</TR>
<% end %>
</TBODY>
</TABLE>
<% if view.errtxt then %>
<p class="error"><%= html.html_escape(view.errtxt) %></p>
<% end %>
<% if #view.value == 0 then %>
<p>No users found</p>
<% end %>
<% if viewlibrary and viewlibrary.dispatch_component and viewlibrary.check_permission("createuser") then %>
<H2>Create New User</H2>
<form action="<%= html.html_escape(page_info.script .. page_info.prefix .. page_info.controller) %>/createuser" method="POST">
<input class="hidden" type="hidden" name="redir" value="<%= html.html_escape(page_info.orig_action) %>" >
<dl><dt></dt><dd><input class="submit" type="submit" value="Create"></dd></dl>
</form>
<% end %>
</DL>
This diff is collapsed.
# Prefix and controller are already known at this point
# Cat Group Tab Action
Applications 88Voicemail Users editusers
Applications 88Voicemail Voicemail listmessages
Applications 88Voicemail Voicemail listmymessages
Applications 88Voicemail Settings editmyusersettings
Applications 88Voicemail Config editconfig
GUEST=vmail:processdialplanxml,vmail:processdirectoryxml
USER=vmail:listusers,vmail:listmymessages,vmail:downloadmymessage,vmail:deletemymessage,vmail:editmyusersettings,vmail:forwardmymessage,vmail:emailmymessage
EDITOR=vmail:editusers,vmail:createuser,vmail:deleteuser,vmail:editusersettings
EXPERT=vmail:editconfig,vmail:listmessages,vmail:downloadmessage,vmail:deletemessage,vmail:forwardmessage,vmail:emailmessage
ADMIN=vmail:listmessages,vmail:downloadmessage,vmail:deletemessage,vmail:forwardmessage,vmail:emailmessage,vmail:editusersettings,vmail:listusers,vmail:editusers,vmail:createuser,vmail:deleteuser,vmail:editconfig
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment