# HG changeset patch
# User bsw
# Date 1613303199 -3600
# Node ID 3fb752f4afcb071ad6e1eb462ae80abf1a422f77
# Parent 036703d1b400cde6eb7e42f9abd05c8b41ffa6fa
Cleanup of configuration files
diff -r 036703d1b400 -r 3fb752f4afcb app/main/_prefork/10_init.lua
--- a/app/main/_prefork/10_init.lua Fri Feb 12 17:59:21 2021 +0100
+++ b/app/main/_prefork/10_init.lua Sun Feb 14 12:46:39 2021 +0100
@@ -126,6 +126,10 @@
if not config.oauth2.dynamic_registration_lifetime then
config.oauth2.dynamic_registration_lifetime = 60 * 60 * 24
end
+ if config.oauth2.refresh_pause < config.oauth2.refresh_grace_period then
+ print("ERROR: config.auth2.refresh_pause is smaller than config.oauth2.refresh_grace_period")
+ os.exit()
+ end
end
if not config.database then
diff -r 036703d1b400 -r 3fb752f4afcb config/_ldap.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config/_ldap.lua Sun Feb 14 12:46:39 2021 +0100
@@ -0,0 +1,59 @@
+config.ldap = {
+ hosts = {
+ {
+ { uri = "ldap://192.168.1.1", tls = true, timeout = 5 },
+ { uri = "ldap://192.168.1.2", tls = true, timeout = 5 },
+ },
+ { uri = "ldap://192.168.1.3", tls = true, timeout = 5 },
+ },
+ base = "dc=example,dc=org",
+ bind_as = { dn = "cn=admin,dc=example,dc=org", password = "secure" },
+ member = {
+ registration = "auto",
+ scope = "subtree",
+ login_normalizer = function (login)
+ return login:lower()
+ end,
+ login_filter_map = function (login)
+ return "(uid=" .. ldap.escape_filter(login) .. ")"
+ end,
+ login_map = function (ldap_entry)
+ return ldap_entry.uid[1]
+ end,
+ uid_filter_map = function (uid)
+ return "(uidNumber=" .. ldap.escape_filter(uid) .. ")"
+ end,
+ uid_map = function (ldap_entry)
+ return ldap_entry.uidNumber[1]
+ end,
+ fetch_attr = { "uid", "uidNumber", "givenName", "sn", "displayName", "memberof" },
+ attr_map = function (ldap_entry, member)
+ member.identification = ldap_entry.givenName[1] .. " " .. ldap_entry.sn[1]
+ member.name = ldap_entry.displayName[1]
+ end,
+ privilege_map = function (ldap_entry, member)
+ local privileges
+ if ldap_entry.dn:match("ou=people,dc=example,dc=org") then
+ privileges = {
+ { unit_id = 1, voting_right = true, polling_right = true },
+ { unit_id = 2, voting_right = true, polling_right = false },
+ { unit_id = 3, voting_right = false, polling_right = true }
+ }
+ elseif ldap_entry.dn:match("ou=employees,dc=example,dc=org$") then
+ privileges = {
+ { unit_id = 1, voting_right = false, polling_right = true },
+ { unit_id = 2, voting_right = false, polling_right = true },
+ { unit_id = 3, voting_right = true, polling_right = false }
+ }
+ elseif ldap_entry.dn:match("ou=member,dc=example,dc=org$") then
+ privileges = {
+ { unit_id = 1, voting_right = true, polling_right = false }
+ }
+ end
+ return privileges
+ end,
+ cache_passwords = true,
+ locked_profile_fields = { name = true }
+ }
+}
+
diff -r 036703d1b400 -r 3fb752f4afcb config/_ldap_ad.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config/_ldap_ad.lua Sun Feb 14 12:46:39 2021 +0100
@@ -0,0 +1,66 @@
+local function str2hex(s)
+ local t = {string.byte(s, 1, #s)}
+ local f = string.format
+ for i = 1, #t do t[i] = f("\\%02x", t[i]) end
+ return table.concat(t)
+end
+
+config.ldap = {
+ hosts = {
+ { uri = "ldap://192.168.1.1", tls = true, timeout = 5 },
+ { uri = "ldap://192.168.1.2", tls = true, timeout = 5 }
+ },
+ base = "CN=Users,DC=example,DC=org",
+ bind_as = { dn = "CN=LiquidFeedback Service,CN=Users,DC=example,DC=org", password = "secure" },
+ member = {
+ registration = "auto",
+ scope = "subtree",
+ login_normalizer = function (login)
+ return login:lower()
+ end,
+ login_filter_map = function (login)
+ return "(sAMAccountName=" .. ldap.escape_filter(login) .. ")"
+ end,
+ login_map = function (ldap_entry)
+ return ldap_entry.sAMAccountName[1]
+ end,
+ uid_filter_map = function (uid)
+ return "(objectGUID=" .. uid .. ")"
+ end,
+ uid_map = function (ldap_entry)
+ return str2hex(ldap_entry.objectGUID[1])
+ end,
+ allowed_map = function (ldap_entry)
+ local allowed = false
+ if ldap_entry.memberOf then
+ for i, group in ipairs(ldap_entry.memberOf) do
+ if group == "CN=LiquidFeedback User,CN=Users,DC=example,DC=org" then
+ allowed = true
+ end
+ end
+ end
+ return allowed
+ end,
+ fetch_attr = { "sAMAccountName", "objectGUID", "givenName", "name", "displayName", "memberOf" },
+ attr_map = function (ldap_entry, member)
+ member.identification = ldap_entry.givenName[1] .. " " .. ldap_entry.name[1]
+ member.name = ldap_entry.displayName[1]
+ end,
+ privilege_map = function (ldap_entry, member)
+ local privileges = {}
+ if ldap_entry.memberOf then
+ for i, group in ipairs(ldap_entry.memberOf) do
+ if group == "CN=LiquidFeedback User,CN=Users,DC=example,DC=org" then
+ table.insert(privileges,
+ { unit_id = 1, voting_right = true, polling_right = true }
+ )
+ end
+ end
+ end
+ return privileges
+ end,
+ cache_passwords = true,
+ locked_profile_fields = { name = true }
+ }
+}
+
diff -r 036703d1b400 -r 3fb752f4afcb config/_lf4rcs.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/config/_lf4rcs.lua Sun Feb 14 12:46:39 2021 +0100
@@ -0,0 +1,115 @@
+-- Configuration of lf4rcs
+-- ------------------------------------------------------------------------
+config.lf4rcs = {}
+
+-- Example configuration for controlling a Git repository
+
+config.lf4rcs.git = {
+
+ render_draft_reference = function(url, draft)
+ if not draft.external_reference then return end
+ ui.tag{ content = _"Changeset:" }
+ slot.put(" ")
+ ui.link{
+ text = draft.external_reference,
+ external = url .. ";a=commit;h=" .. draft.external_reference
+ }
+ end,
+
+ get_remote_user = function()
+ return os.getenv("REMOTE_USER")
+ end,
+
+ get_branches = function(path, exec)
+ local branches = {}
+ for line in io.lines() do
+ local oldrev, newrev, branch = string.match(line, "([^ ]+) ([^ ]+) refs/heads/(.+)")
+ if not branch then
+ return nil, "unexpected format from git hook environment"
+ end
+ branches[branch] = { newrev }
+ end
+ return branches
+ end,
+
+ commit = function(path, exec, branch, target_node_id, close_message, merge_message)
+ if merge_message then
+ exec("git", "-C", path, "checkout", "-f", "master")
+ exec("git", "-C", path, "merge", target_node_id, "-m", merge_message)
+ exec("git", "-C", path, "push", "origin", "master")
+ end
+ end
+
+}
+
+-- Example configuration for controlling a Mercurial repository
+config.lf4rcs.hg = {
+
+ working_branch_name = "work",
+
+ render_draft_reference = function(url, draft)
+ if not draft.external_reference then return end
+ ui.tag{ content = _"Changeset graph:" }
+ slot.put(" ")
+ ui.link{
+ text = draft.external_reference,
+ external = url .. "/graph/" .. draft.external_reference
+ }
+ end,
+
+ get_remote_user = function()
+ return os.getenv("REMOTE_USER")
+ end,
+
+ get_branches = function(path, exec)
+ local first_node_id = os.getenv("HG_NODE")
+ if not first_node_id then
+ return nil, "internal error, no first node ID available"
+ end
+ local hg_log = exec(
+ "hg", "log", "-R", path, "-r", first_node_id .. ":", "--template", "{branches}\n"
+ )
+ local branches = {}
+ for branch in hg_log:gmatch("(.-)\n") do
+ if branch == "" then branch = "default" end
+ if not branches[branch] then
+ branches[branch] = {}
+ local head_lines = exec(
+ "hg", "heads", "-R", path, "--template", "{node}\n", branch
+ )
+ for node_id in string.gmatch(head_lines, "[^\n]+") do
+ table.insert(branches[branch], node_id)
+ end
+ end
+ end
+ return branches
+ end,
+
+ extra_checks = function(path, exec)
+ local result = exec("hg", "heads", "-t", "-c")
+ for branch in string.gmatch(result, "[^\n]+") do
+ if branch == lf4rcs.config.hg.working_branch_name then
+ return nil, "open head found for branch " .. lf4rcs.config.hg.working_branch_name
+ end
+ end
+ return true
+ end,
+
+ commit = function(path, exec, branch, target_node_id, close_message, merge_message)
+ exec("hg", "up", "-R", path, "-C", "-r", target_node_id)
+ exec("hg", "commit", "-R", path, "--close-branch", "-m", close_message)
+ if merge_message then
+ exec("hg", "up", "-R", path, "-C", "-r", "default")
+ exec("hg", "merge", "-R", path, "-r", "tip")
+ exec("hg", "commit", "-R", path, "-m", merge_message)
+ end
+ end
+
+}
+
+-- Grace period after creating an initiative for pushing changes during verification phase
+-- disabled by default (nil), use PostgreSQL interval notation
+-- config.lf4rcs.push_grace_period = nil
+
+lf4rcs.init()
+
diff -r 036703d1b400 -r 3fb752f4afcb config/example.lua
--- a/config/example.lua Fri Feb 12 17:59:21 2021 +0100
+++ b/config/example.lua Sun Feb 14 12:46:39 2021 +0100
@@ -4,40 +4,7 @@
-- Name of this instance, defaults to name of config file
-- ------------------------------------------------------------------------
-config.instance_name = "Instance name"
-
-
--- Information about service provider (HTML)
--- ------------------------------------------------------------------------
-config.app_service_provider = "Snake Oil
10000 Berlin
Germany"
-
-
--- A HTML formatted text the user has to accept while registering
--- ------------------------------------------------------------------------
-config.use_terms = "
Insert terms here
" - - --- Checkbox(es) the user has to accept while registering --- ------------------------------------------------------------------------ ---[[ -config.use_terms_checkboxes = { - { - name = "terms_of_use_v1", - html = "I accept the terms of use.", - not_accepted_error = "You have to accept the terms of use to be able to register." - }, - { - name = "extra_terms_of_use_v1", - html = "I accept the extra terms of use.", - not_accepted_error = "You have to accept the extra terms of use to be able to register." - } -} ---]] - --- Absolute base url of application --- ------------------------------------------------------------------------ -config.absolute_base_url = "http://example.com/" -config.localhost = false +config.instance_name = "Example Organisation" -- Connection information for the LiquidFeedback database @@ -45,31 +12,32 @@ config.database = { engine='postgresql', dbname='liquid_feedback' } --- Location of the rocketwiki binaries +-- Absolute base url of application +-- ------------------------------------------------------------------------ +config.absolute_base_url = "https://example.org/" + + +-- Network interface to bind to +-- ------------------------------------------------------------------------ +-- Available options: +-- true: bind to localhost (default) +-- false: bind to all interface -- ------------------------------------------------------------------------ -config.enforce_formatting_engine = "markdown2" -config.formatting_engines = { - { id = "markdown2", - name = "python-markdown2", - executable = "markdown2", - args = {'-s', 'escape', '-x', 'nofollow,wiki-tables'}, - remove_images = true - }, --- { id = "markdown_py", --- name = "Python Markdown", --- executable = "markdown_py", --- args = {'-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'}, --- remove_images = true --- }, --- { id = "rocketwiki", --- name = "RocketWiki", --- executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb" --- }, --- { id = "compat", --- name = "Traditional WIKI syntax", --- executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat" --- }, -} +-- config.localhost = true + + +-- Network port to bind to, default port 8080 +-- ------------------------------------------------------------------------ +-- config.port = 8080 + + +-- Serving content via IPV6 +-- ------------------------------------------------------------------------ +-- Available options: +-- nil or false: do not serve via IPv6 (default) +-- true: serve via IPv6 +-- ------------------------------------------------------------------------ +-- config.ipv6 = false -- Public access level @@ -88,7 +56,12 @@ -- "everything" -- -> Show everything a member can see, including profile pages -- ------------------------------------------------------------------------ -config.public_access = "authors_pseudonymous" +config.public_access = "none" + + +-- Information about service provider (HTML) +-- ------------------------------------------------------------------------ +config.app_service_provider = "Snake OilInsert terms here
" + + +-- Checkbox(es) the user has to accept while registering +-- ------------------------------------------------------------------------ +-- config.use_terms_checkboxes = { +-- { +-- name = "terms_of_use_v1", +-- html = "I accept the terms of use.", +-- not_accepted_error = "You have to accept the terms of use to be able to register." +-- }, +-- { +-- name = "extra_terms_of_use_v1", +-- html = "I accept the extra terms of use.", +-- not_accepted_error = "You have to accept the extra terms of use to be able to register." +-- } +-- } + -- after how long is a user considered inactive and the trustee will see warning, -- notation is according to postgresql intervals, default: no warning at all -- ------------------------------------------------------------------------ @@ -125,8 +118,8 @@ -- after which time a user is advised (_soft) or forced (_hard) to check -- unit and area delegations. default: no check at all -- ------------------------------------------------------------------------ +-- config.check_delegations_interval_soft = "3 months" -- config.check_delegations_interval_hard = "6 months" --- config.check_delegations_interval_soft = "3 months" -- default option when checking delegations @@ -174,11 +167,6 @@ -- config.password_hash_max_rounds = 20000 --- Supply custom url for avatar/photo delivery --- ------------------------------------------------------------------------ --- config.fastpath_url_func = nil - - -- Local directory for database dumps offered for download -- ------------------------------------------------------------------------ -- config.download_dir = nil @@ -197,6 +185,32 @@ -- photo = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end --} +-- Initiative attachments +-- ------------------------------------------------------------------------ +-- config.attachments = {} + +-- Conversion function for recoding attachments +-- ------------------------------------------------------------------------ +-- config.attachments.convert_func = function(data) +-- return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") +-- end + +-- Custom UI colors, defaults to green/blue +-- ------------------------------------------------------------------------ +-- config.style = { +-- color_md = { +-- primary = "green", +-- primary_contrast = "dark", +-- accent = "blue", +-- accent_contrast = "dark" +-- } +-- } + +-- Member profile fields, defaults to no extra fields +-- ------------------------------------------------------------------------ +-- config.member_profile_fields = {} + + -- Display a html formatted public message of the day -- ------------------------------------------------------------------------ @@ -208,16 +222,6 @@ -- config.motd_intern = "The MOTD is formatted with HTML
" --- Integration of Etherpad, disabled by default --- ------------------------------------------------------------------------ ---config.etherpad = { --- base_url = "http://example.com:9001/", --- api_base = "http://localhost:9001/", --- api_key = "mysecretapikey", --- group_id = "mygroupname", --- cookie_path = "/" ---} - -- Free timings -- ------------------------------------------------------------------------ @@ -264,121 +268,6 @@ } --]] --- Configuration of lf4rcs --- ------------------------------------------------------------------------ --- config.lf4rc = {} - --- Example configuration for controlling a Git repository ---[[ -config.lf4rcs.git = { - - render_draft_reference = function(url, draft) - if not draft.external_reference then return end - ui.tag{ content = _"Changeset:" } - slot.put(" ") - ui.link{ - text = draft.external_reference, - external = url .. ";a=commit;h=" .. draft.external_reference - } - end, - - get_remote_user = function() - return os.getenv("REMOTE_USER") - end, - - get_branches = function(path, exec) - local branches = {} - for line in io.lines() do - local oldrev, newrev, branch = string.match(line, "([^ ]+) ([^ ]+) refs/heads/(.+)") - if not branch then - return nil, "unexpected format from git hook environment" - end - branches[branch] = { newrev } - end - return branches - end, - - commit = function(path, exec, branch, target_node_id, close_message, merge_message) - if merge_message then - exec("git", "-C", path, "checkout", "-f", "master") - exec("git", "-C", path, "merge", target_node_id, "-m", merge_message) - exec("git", "-C", path, "push", "origin", "master") - end - end - -} - --- Example configuration for controlling a Mercurial repository -config.lf4rcs.hg = { - - working_branch_name = "work", - - render_draft_reference = function(url, draft) - if not draft.external_reference then return end - ui.tag{ content = _"Changeset graph:" } - slot.put(" ") - ui.link{ - text = draft.external_reference, - external = url .. "/graph/" .. draft.external_reference - } - end, - - get_remote_user = function() - return os.getenv("REMOTE_USER") - end, - - get_branches = function(path, exec) - local first_node_id = os.getenv("HG_NODE") - if not first_node_id then - return nil, "internal error, no first node ID available" - end - local hg_log = exec( - "hg", "log", "-R", path, "-r", first_node_id .. ":", "--template", "{branches}\n" - ) - local branches = {} - for branch in hg_log:gmatch("(.-)\n") do - if branch == "" then branch = "default" end - if not branches[branch] then - branches[branch] = {} - local head_lines = exec( - "hg", "heads", "-R", path, "--template", "{node}\n", branch - ) - for node_id in string.gmatch(head_lines, "[^\n]+") do - table.insert(branches[branch], node_id) - end - end - end - return branches - end, - - extra_checks = function(path, exec) - local result = exec("hg", "heads", "-t", "-c") - for branch in string.gmatch(result, "[^\n]+") do - if branch == lf4rcs.config.hg.working_branch_name then - return nil, "open head found for branch " .. lf4rcs.config.hg.working_branch_name - end - end - return true - end, - - commit = function(path, exec, branch, target_node_id, close_message, merge_message) - exec("hg", "up", "-R", path, "-C", "-r", target_node_id) - exec("hg", "commit", "-R", path, "--close-branch", "-m", close_message) - if merge_message then - exec("hg", "up", "-R", path, "-C", "-r", "default") - exec("hg", "merge", "-R", path, "-r", "tip") - exec("hg", "commit", "-R", path, "-m", merge_message) - end - end - -} - --- Grace period after creating an initiative for pushing changes during verification phase --- disabled by default (nil), use PostgreSQL interval notation --- config.lf4rcs.push_grace_period = nil - -lf4rcs.init() ---]] -- External references -- ------------------------------------------------------------------------ @@ -399,45 +288,44 @@ end --]] + +-- Configuration of OAuth2 service, defaults to OAuth2 disabled +-- ------------------------------------------------------------------------ +-- config.oauth2 = {} + +-- Additional scopes +-- config.oauth2.available_scopes = { +-- { scope = "privA", name = { de = "Beispielprivileg A", en = "Example privilege A" } }, +-- { scope = "privB", name = { de = "Beispielprivileg B", en = "Example privilege B" } } +-- } + +-- OAuth2 endpoint magic string for dynamic app registration +-- ------------------------------------------------------------------------ +-- config.oauth2.endpoint_magic = "liquidfeedback_client_redirection_endpoint" + +-- OAuth2 Token lifetime and timings +-- ------------------------------------------------------------------------ +-- config.oauth2.authorization_code_lifetime = 5 * 60 +-- config.oauth2.refresh_token_lifetime = 60 * 60 * 24 * 30 * 3 +-- config.oauth2.refresh_pause = 60 +-- config.oauth2.refresh_grace_period = 60 +-- config.oauth2.access_token_lifetime = 60 * 60 + + + -- Admin logger -- ------------------------------------------------------------------------ -- Logging administrative activities -- disabled by default ---[[ -config.admin_logger = function(params) - - local adminid = app.session.member_id - local adminname = app.session.member.name - local url = params._webmcp_path - - -- do something (e.g. calling 'logger' via extos.pfilter) - -end ---]] +-- config.admin_logger = function(params) +-- local adminid = app.session.member_id +-- local adminname = app.session.member.name +-- local url = params._webmcp_path +-- -- do something (e.g. calling 'logger' via extos.pfilter) +-- end --- Network interface to bind to --- ------------------------------------------------------------------------ --- Available options: --- true: bind to localhost (default) --- false: bind to all interface --- ------------------------------------------------------------------------ --- config.localhost = true - - --- Network port to bind to --- ------------------------------------------------------------------------ --- config.port = 8080 - - --- Serving content via IPV6 --- ------------------------------------------------------------------------ --- Available options: --- nil or false: do not serve via IPv6 (default) --- true: serve via IPv6 --- ------------------------------------------------------------------------ --- config.ipv6 = false -- Application server fork configuration @@ -483,28 +371,42 @@ -- ------------------------------------------------------------------------ -- uncomment the following line to enable debug trace -- ------------------------------------------------------------------------ -config.enable_debug_trace = true +-- config.enable_debug_trace = true + + +-- Configuration of lf4rcs, disabled by default +-- for example configration see _lf4rcs.lua +-- ------------------------------------------------------------------------ +-- execute.config("_lf4rcs") + + +-- Configuration of ldap authentication, disabled by default +-- for example configration, see _ldap.lua +-- for active directory example, see _ldap_ad.lua +-- ------------------------------------------------------------------------ +-- execute.config("_ldap") +-- execute.config("_ldap_ad") -config.fork = { - pre =1, min = 1, max = 1, max_requests = 1, min_requests = 1 -} - -config.localhost = true +-- Integration of Etherpad, disabled by default +-- ------------------------------------------------------------------------ +--config.etherpad = { +-- base_url = "http://example.com:9001/", +-- api_base = "http://localhost:9001/", +-- api_key = "mysecretapikey", +-- group_id = "mygroupname", +-- cookie_path = "/" +--} -config.oauth2 = { - available_scopes = { - { scope = "read", name = { de = "Lesen", en = "Read data" } }, - { scope = "write", name = { de = "Schreiben", en = "Write data" } }, - { scope = "privA", name = { de = "Beispielprivileg A", en = "Example privilege A" } }, - { scope = "privB", name = { de = "Beispielprivileg B", en = "Example privilege B" } } - }, - authorization_code_lifetime = 5 * 60, - refresh_token_lifetime = 60 * 60 * 24 * 30 * 3, - refresh_pause = 60, - refresh_grace_period = 60, - access_token_lifetime = 60 * 60, - -- NOTE for init.lua : check for refresh_pause >= refresh_grace_period - endpoint_magic = "liquidfeedback_client_redirection_endpoint" +-- Integration of FirstLife +-- ------------------------------------------------------------------------ +--[[ +config.firstlife = { + coordinates = "", + areaviewer_url = "about:blank", + inputmap_url = "about:blank" } +config.allow_new_draft_callback = true +--]] +