path: build/plist/**/*.html
if: ${{ matrix.env.CC == 'clang' && failure() }}
+ - name: Add OpenResty repository
+ shell: bash
+ run: |
+ wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
+ echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list
+
+ sudo apt-get update
+
+ - name: Setup git (containers)
+ if: ${{ env.USE_DOCKER == 1 }}
+ shell: bash
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
+
- name: Install test requisites
run: |
# Temporarily replace ucf (for config merge) with cp since it's
sudo apt-get install ${APT_OPTS} \
apparmor-utils \
ldap-utils \
+ openresty \
slapd
sudo mv -f /usr/bin/ucf.disabled /usr/bin/ucf
slapd
+ - name: Build certificates for REST tests
+ run: |
+ cp -r raddb/certs raddb/restcerts
+ cd ./raddb/restcerts && make ca && make server
+
- name: Setup test databases
run: |
for i in \
postgresql-setup.sh \
mysql-setup.sh \
+ openresty-setup.sh \
ldap-setup.sh \
ldap2-setup.sh; do
--- /dev/null
+#!/bin/sh -e
+#
+# ### This is a script to setup an openresty web server for testing rlm_smtp
+#
+
+#
+# Declare the important path variables
+#
+
+# Base Directories
+BASEDIR=$(git rev-parse --show-toplevel)
+BUILDDIR="${BASEDIR}/build/ci/openresty"
+CIDIR="${BASEDIR}/scripts/ci"
+
+# Directories for openresty processes
+ROOTDIR="${BUILDDIR}/html"
+APIDIR="${BUILDDIR}/api"
+LOGDIR="${BUILDDIR}/logs"
+CERTDIR="${BUILDDIR}/certs"
+CERTSRCDIR="${BASEDIR}/raddb/restcerts"
+PASSWORD="whatever"
+
+# Important files for running openresty
+CONF="${BUILDDIR}/nginx.conf"
+
+#
+# Prepare the directories and files needed for running openresty
+#
+
+# Stop any currently running openresty instance
+echo "Checking for a running openresty instance"
+if [ -e "${LOGDIR}/nginx.pid" ]
+then
+ echo "Stopping the current openresty instance"
+ kill "$(cat ${LOGDIR}/nginx.pid)"
+ rm -r "${BUILDDIR}"
+fi
+
+# Create the directories
+mkdir -p "${BUILDDIR}" "${ROOTDIR}" "${APIDIR}" "${LOGDIR}" "${CERTDIR}"
+
+# Create the certificate
+echo "Generating the certificates"
+openssl pkcs8 -in ${CERTSRCDIR}/server.key -passin pass:${PASSWORD} -out ${CERTDIR}/server.key
+cat ${CERTSRCDIR}/server.pem ${CERTSRCDIR}/ca.pem > ${CERTDIR}/server.pem
+
+# Create nginx.conf file
+echo "Generating the openresty configuration file"
+touch "${CONF}"
+
+# Build nginx.conf
+echo "
+#
+worker_processes 1;
+error_log ${LOGDIR}/error.log;
+pid ${LOGDIR}/nginx.pid;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /usr/local/openresty/nginx/conf/mime.types;
+ default_type text/plain;
+
+ sendfile on;
+
+ server {
+ listen 8080;
+ server_name localhost;
+
+ location / {
+ root ${ROOTDIR};
+ index index.html;
+ }
+
+ location ~ ^/user(.*)$ {
+ default_type 'application/json';
+ add_header 'Content-Type' 'application/json';
+ content_by_lua_file ${APIDIR}/json-api.lua;
+ }
+
+ location ~ ^/post(.*)$ {
+ content_by_lua_file ${APIDIR}/post-api.lua;
+ }
+ }
+
+ server {
+ listen 8443 ssl;
+ server_name localhost;
+
+ ssl_certificate ${CERTDIR}/server.pem;
+ ssl_certificate_key ${CERTDIR}/server.key;
+
+ ssl_session_cache shared:SSL:1m;
+ ssl_session_timeout 5m;
+
+ ssl_ciphers HIGH:!aNULL:!MD5;
+ ssl_prefer_server_ciphers on;
+
+ location / {
+ root ${ROOTDIR};
+ index index.html;
+ }
+
+ location ~ ^/user(.*)$ {
+ default_type 'application/json';
+ add_header 'Content-Type' 'application/json';
+ content_by_lua_file ${APIDIR}/json-api.lua;
+ }
+
+ location ~ ^/post(.*)$ {
+ content_by_lua_file ${APIDIR}/post-api.lua;
+ }
+
+ location ~ ^/auth(.*)$ {
+ content_by_lua_file ${APIDIR}/auth-api.lua;
+ auth_basic 'Auth Area';
+ auth_basic_user_file ${BUILDDIR}/.htpasswd;
+ }
+ }
+}
+
+" >"${CONF}"
+
+echo "Copy lua scripts into place"
+cp ${CIDIR}/openresty/*.lua "${APIDIR}"
+
+echo "Copy sample data into place"
+cp "${CIDIR}/openresty/test.txt" "${ROOTDIR}"
+
+echo "Copy htpasswd into place"
+cp "${CIDIR}/openresty/.htpasswd" "${BUILDDIR}"
+
+#
+# Run the openresty instance
+#
+echo "Starting openresty"
+openresty -c ${CONF} -p ${BUILDDIR}
+echo "Running openresty on port 8080 and 8443, accepting all local connections"
--- /dev/null
+Bob:$apr1$4AtMvgrH$pWCOxq7gq1N2AyeE7GT3R/
--- /dev/null
+-- Simple API for checking POST data
+
+-- Get the request path
+local reqPath = ngx.var.uri
+-- Get the request method (POST, GET etc..)
+local reqMethod = ngx.var.request_method
+-- Get any URI arguments
+local uriArgs = ngx.req.get_uri_args()
+-- Get any POST arguments
+ngx.req.read_body()
+local postArgs = ngx.req.get_post_args()
+
+-- We only reply to POST requests
+if reqMethod ~= "POST"
+then
+ return false
+end
+
+ngx.say("Section: ", uriArgs.section, ", User: ", postArgs.user, ", Authenticated: true")
--- /dev/null
+-- Based on https://github.com/bambattajb/openresty-api-example
+
+-- Helper functions
+function strSplit(delim,str)
+ local t = {}
+
+ for substr in string.gmatch(str, "[^".. delim.. "]*") do
+ if substr ~= nil and string.len(substr) > 0 then
+ table.insert(t,substr)
+ end
+ end
+
+ return t
+end
+
+-- Read body being passed
+-- Required for ngx.req.get_body_data()
+ngx.req.read_body()
+-- Parser for sending JSON back to the client
+local cjson = require("cjson")
+-- Get the request path
+local reqPath = ngx.var.uri
+-- Get the request method (POST, GET etc..)
+local reqMethod = ngx.var.request_method
+-- Get any URI arguments
+local uriArgs = ngx.req.get_uri_args()
+-- Parse the body data as JSON
+local body = ngx.req.get_body_data() ==
+ -- This is like a ternary statement for Lua
+ -- It is saying if doesn't exist at least
+ -- define as empty object
+ nil and {} or cjson.decode(ngx.req.get_body_data());
+
+Api = {}
+Api.__index = Api
+-- Declare API not yet responded
+Api.responded = false;
+-- Function for checking input from client
+function Api.endpoint(method, path, callback)
+
+ -- return false if method doesn't match
+ if reqMethod ~= method
+ then
+ return false
+ end
+
+ -- If API already responded
+ if Api.responded then
+ return false
+ end
+
+ -- KeyData = params passed in path
+ local keyData = {}
+ -- Unaltered version of path
+ local origPath = reqPath
+ -- If this endpoint has params
+ if string.find(path, "<(.-)>")
+ then
+ -- Split origin and passed path sections
+ local splitPath = strSplit("/", path)
+ local splitReqPath = strSplit("/", reqPath)
+ -- Iterate over splitPath
+ for i, k in pairs(splitPath) do
+ -- If chunk contains <something>
+ if string.find(k, "<(.-)>")
+ then
+ if not splitReqPath[i] then
+ reqPath = origPath
+ return false
+ end
+ -- Add to keyData
+ keyData[string.match(k, "%<(%a+)%>")] = splitReqPath[i]
+ -- Replace matches with default for validation
+ reqPath = string.gsub(reqPath, splitReqPath[i], k)
+ end
+ end
+ end
+
+ -- return false if path doesn't match anything
+ if reqPath ~= path
+ then
+ reqPath = origPath
+ return false;
+ end
+
+ -- Make sure we don't run this again
+ Api.responded = true;
+
+ return callback(body, keyData);
+end
+
+-- Used in the accounting test
+Api.endpoint('POST', '/user/<username>/mac/<client>',
+ function(body, keyData)
+ local returnData = {}
+ returnData["control:Tmp-String-0"] = uriArgs.section
+ returnData["control:Tmp-String-1"] = {
+ reqMethod,
+ reqPath
+ }
+ returnData["control:User-Name"] = {
+ op = ":=",
+ value = keyData.username
+ }
+ returnData["control:NAS-IP-Address"] = {
+ op = "+=",
+ value = body.NAS or body['NAS-IP-Address'].value
+ }
+ returnData["control:Tmp-String-2"] = {
+ op = "^=",
+ value = keyData.username
+ }
+ return ngx.say(cjson.encode(returnData))
+ end
+)
+
+-- Used in the authorize test
+Api.endpoint('GET', '/user/<username>/mac/<client>',
+ function(body, keyData)
+ local returnData = {}
+ returnData["control:Tmp-String-0"] = uriArgs.section
+ returnData["control:Tmp-String-1"] = {
+ reqMethod,
+ reqPath
+ }
+ returnData["control:User-Name"] = {
+ op = ":=",
+ value = keyData.username
+ }
+ returnData["control:Tmp-String-2"] = {
+ op = "^=",
+ value = keyData.username
+ }
+ return ngx.say(cjson.encode(returnData))
+ end
+)
+
+-- Simple reflection of a URI argument
+Api.endpoint('GET', '/user/<username>/reflect/',
+ function(body, keyData)
+ local returnData = {}
+ returnData["station"] = uriArgs.station
+ return ngx.say(cjson.encode(returnData))
+ end
+)
--- /dev/null
+-- Simple API for checking POST data
+
+-- Get the request path
+local reqPath = ngx.var.uri
+-- Get the request method (POST, GET etc..)
+local reqMethod = ngx.var.request_method
+-- Get any URI arguments
+local uriArgs = ngx.req.get_uri_args()
+-- Get any POST arguments
+ngx.req.read_body()
+local postArgs = ngx.req.get_post_args()
+
+-- We only reply to POST requests
+if reqMethod ~= "POST"
+then
+ return false
+end
+
+ngx.say("Section: ", uriArgs.section, ", User: ", postArgs.user)
--- /dev/null
+Sample text response