require("luamods/command")
require("luamods/layout")
require("luamods/cgi")

local escape_lua_pattern
do
    local matches =
    {
        ["^"] = "%^";
        ["$"] = "%$";
        ["("] = "%(";
        [")"] = "%)";
        ["%"] = "%%";
        ["."] = "%.";
        ["["] = "%[";
        ["]"] = "%]";
        ["*"] = "%*";
        ["+"] = "%+";
        ["-"] = "%-";
        ["?"] = "%?";
        ["\0"] = "%z";
    }

    escape_lua_pattern = function(s)
        return (s:gsub(".", matches))
    end
end 

openvpn_conf="/etc/openvpn/openvpn.conf"
openvpn_login="/etc/openvpn/client-login"

userLevel = db.getPriv(layout.username) or 1

if (userLevel == 1) then
    buttonControl = " disabled"
    inputControl = " readonly"
    scriptControl = "//"
else
    buttonControl = ""
    inputControl = ""
    scriptControl = ""
end

header = layout.getHeader()
footer = layout.getFooter()

if (cgi.post.submitButton == "Save and Apply") and (userLevel ~= 1) then
    conf = command.ex("cat "..openvpn_conf) or ""
    login = command.ex("cat "..openvpn_login) or ""
    local newClient = cgi.post.client or "guinnux"
    local newPass = cgi.post.password or "g$uinnux"
    local newServer = cgi.post.server or "www.ostb.co.za"
    local newPort = cgi.post.port or "1194"
    server,port = conf:match("remote%s+([^\r\n]+)%s+(%d+)")
    local newConf = conf:gsub("remote%s+"..escape_lua_pattern(server).."%s+"..port, "remote "..newServer.." "..newPort)
    local newEnabled = cgi.post.enable or ""
    command.writefile(openvpn_conf, newConf)
    command.writefile(openvpn_login, newClient.."\n"..newPass.."\n")
    saved = 1
    if newEnabled == "enabled" then
       results = command.ex("systemctl enable \"openvpn@openvpn\" 2>&1") or ""
       results = results..command.ex("systemctl restart \"openvpn@openvpn\" 2>&1") or ""
    else
       results = command.ex("systemctl disable \"openvpn@openvpn\" 2>&1") or ""
       results = results..command.ex("systemctl stop \"openvpn@openvpn\" 2>&1") or ""
    end
end

conf = command.ex("cat "..openvpn_conf) or ""
login = command.ex("cat "..openvpn_login) or ""

server,port = conf:match("remote%s+([^\r\n]+)%s+(%d+)")
client,password = login:match("(.+)\r?\n(.+)")
client = client or ""
password = password or ""
enabled = command.ex("systemctl is-enabled \"openvpn@openvpn\""):match("(enabled)") or ""

content = [[
                    <div id="info">
                        <div style="background:url(images/openvpn.png); background-size:32px; background-repeat:no-repeat; background-position: 20px center;">
                            <center><h1>OpenVPN - Configuration</h1></center>
                        </div>
                    </div>
]]

if (userLevel == 1) then
    content = content .. [[
                    <center><b>Note:</B> Editing this section requires administrator privileges.</center><br>
]]                    
end

if (conf == nil) or (conf == "") then
    -- Bail on error
    content = content .. [[
                    <div id="info">
                        <center>
                            <h2><img src="images/warning.png"/> Cannot read config file</h2>
                            The OpenVPN configuration file "]]..openvpn_conf..[[" is missing, unreadable or empty.
                        </center>
                    </div>
]]
    print(header..content..footer)
    return     
elseif (server == nil) or (port == nil) then
    -- Bail on error
    content = content .. [[
                    <div id="info">
                        <center>
                            <h2><img src="images/warning.png"/> Invalid config file</h2>
                            The OpenVPN configuration file "]]..openvpn_conf..[[" is incomplete or improperly formatted.
                        </center>
                    </div>
]]
    print(header..content..footer)
    return
else
    local enable_checked
    if enabled == "enabled" then enable_checked = " checked " else enable_checked = "" end
    content = content .. [[
                    <div class="formLayoutfull">
                        <form action="openvpn_conf.lua" method="post">
                            <h3>Server configuration</h3>
                            <ul>
                                <li><label style="width:150px; display: inline-block;">Address:</label><input type="text" name="server"]]..inputControl..[[ value="]]..server..[[" size="35"/> <B>:</B>
                                <input type="text" name="port"]]..inputControl..[[ value="]]..port..[[" size="6" maxlength="6"/></li>
                            </ul>
                            <hr>
                            <h3>Client credentials</h3>
                            <ul>
                                <li><label style="width:150px; display: inline-block;">Activate:</label><input type="checkbox" name="enable" value="enabled" ]]..inputControl..enable_checked..[[" size="25"/></li>
                                <li><label style="width:150px; display: inline-block;">Username:</label><input type="text" name="client"]]..inputControl..[[ value="]]..client..[[" size="25"/></li>
                                <li><label style="width:150px; display: inline-block;">Password:</label><input type="text" name="password"]]..inputControl..[[ value="]]..password..[[" size="25"></li>
                            </ul>
                            <br><hr><br>                            
]]
                            
    if (saved == 1) then
        content = content .. [[
                            <b><img src="images/ok.png"/> Changes saved.</b><br><br>
]]
    end
    content = content .. [[
                            <input type="submit" name="submitButton" value="Save and Apply"]]..buttonControl..[[/><br>
                            <small>This will restart the OpenVPN service.</small>
                        </form>
                    </div>
]]
    if (results ~= nil) and (results ~= "") then
        content = content .. [[
                    <br>
                    <div class="formLayoutfull">
                        <b>Restarting OpenVPN service:</b>
                        <pre>
]]..results..[[
                        </pre>
                    </div>
]]
    end
    content = content .. [[
                    <script>
                        function toggleVis(target)
                        {
                            if (target.style.display == "none")
                            {
                                target.style.display = "inline-block";
                            }
                            else
                            {
                                target.style.display = "none";
                            }
                            return false;
                        }
                    </script>
                    <br><img src="images/magnify.png"/> <a href="javascript:void(0)" onclick="toggleVis(document.getElementById('conf'));">View ]]..openvpn_conf..[[</a></a><br>
        
                    <div id="conf" style="display: none;">
                        <pre class="formLayoutfull">
                        <!-- openvpn conf start -->
]]..conf..[[
                        <!-- openvpn conf end -->
                        </pre>
                    </div>
]]  
end

print(header..content..footer)
