Refactored policy structure

Previously, all modules in an org were fully copied into that
org. Now, the only copy of the modules is at modpol.modules, and orgs
have a policy table at [org].policies, which overrides the config
table in any given module.
This commit is contained in:
Nathan Schneider 2022-02-09 22:14:26 -07:00
parent f950b5b94c
commit 2028f1ee85
7 changed files with 76 additions and 52 deletions

View File

@ -18,13 +18,23 @@ function modpol.interactions.get_policy_string(
local this_org = modpol.orgs.get_org(org) local this_org = modpol.orgs.get_org(org)
local this_module = modpol.modules[module_slug] local this_module = modpol.modules[module_slug]
local output = {} local output = {}
if modpol.util.num_pairs(this_module.config) > 0 then if not this_org.policies[module_slug] then
for k, v in pairs(this_module.config) do return "Module not in org"
local this_policy = k .. " - " .. tostring(v) elseif modpol.util.num_pairs(this_module.config) > 0 then
table.insert(output,this_policy) for k, v in pairs(this_module.config) do
end local this_policy = "[Policy error]"
end if this_org.policies[module_slug][k] then
return "Policies:\n" .. table.concat(output, sep) this_policy =
tostring(this_org.policies[module_slug][k])
else
this_policy = tostring(v)
end
table.insert(output, k.." - "..this_policy)
end
return "Policies:\n" .. table.concat(output, sep)
else
return "No policies"
end
end end
-- DASHBOARDS -- DASHBOARDS
@ -143,9 +153,10 @@ function modpol.interactions.org_dashboard(user, org_string)
-- prepare modules menu -- prepare modules menu
local modules = {} local modules = {}
if org.modules then if modpol.modules then
for k,v in pairs(org.modules) do for k,v in pairs(modpol.modules) do
if not v.hide then -- hide utility modules if not v.hide and -- hide utility modules
org.policies[k] then -- org includes it
local module_entry = v.slug local module_entry = v.slug
table.insert(modules, module_entry) table.insert(modules, module_entry)
end end
@ -186,7 +197,7 @@ function modpol.interactions.org_dashboard(user, org_string)
module_result = true module_result = true
end end
end end
local module = org.modules[module_sel] local module = modpol.modules[module_sel]
if module_result then if module_result then
modpol.interactions.binary_poll_user( modpol.interactions.binary_poll_user(
user, user,

View File

@ -33,7 +33,7 @@ function change_modules:initiate(result)
for k, module in pairs(modpol.modules) do for k, module in pairs(modpol.modules) do
if not modpol.modules[module.slug].hide then if not modpol.modules[module.slug].hide then
local in_org = false local in_org = false
if self.org.modules[module.slug] then if self.org.policies[module.slug] then
in_org = true in_org = true
end end
table.insert( table.insert(
@ -97,14 +97,13 @@ end
function change_modules:implement_change() function change_modules:implement_change()
for i,v in ipairs(self.data.add_modules) do for i,v in ipairs(self.data.add_modules) do
local slug = string.match(v,"%[(.+)%]") local slug = string.match(v,"%[(.+)%]")
self.org.modules[slug] = self.org.policies[slug] = {}
modpol.util.copy_table(modpol.modules[slug]) table.sort(self.org.policies)
table.sort(self.org.modules)
end end
for i,v in ipairs(self.data.remove_modules) do for i,v in ipairs(self.data.remove_modules) do
local slug = string.match(v,"%[(.+)%]") local slug = string.match(v,"%[(.+)%]")
self.org.modules[slug] = nil self.org.policies[slug] = nil
table.sort(self.org.modules) table.sort(self.org.policies)
end end
-- announce and shut down -- announce and shut down
modpol.interactions.message_org( modpol.interactions.message_org(

View File

@ -22,8 +22,9 @@ change_policy.config = {
function change_policy:initiate(result) function change_policy:initiate(result)
-- prepare module options -- prepare module options
local available_modules = {} local available_modules = {}
for k,org_mod in pairs(self.org.modules) do for k,org_mod in pairs(modpol.modules) do
if not org_mod.hide then if not org_mod.hide and
self.org.policies[k] then
available_modules[org_mod.slug] = modpol.util.copy_table(org_mod) available_modules[org_mod.slug] = modpol.util.copy_table(org_mod)
end end end end
local modules_list = {} local modules_list = {}
@ -48,7 +49,7 @@ function change_policy:initiate(result)
self.initiator, "Choose a module to change policies for:", self.initiator, "Choose a module to change policies for:",
modules_list, modules_list,
function(mod_choice) function(mod_choice)
local this_module = self.org.modules[mod_choice] local this_module = modpol.modules[mod_choice]
local module_policies = this_module.config local module_policies = this_module.config
local policy_list = {} local policy_list = {}
for k,v in pairs(module_policies) do for k,v in pairs(module_policies) do
@ -70,10 +71,9 @@ function change_policy:initiate(result)
function(policy_choice) function(policy_choice)
modpol.interactions.text_query( modpol.interactions.text_query(
self.initiator, self.initiator,
"Use carefully!\n" ..
"Current " .. policy_choice .. " value: " .. "Current " .. policy_choice .. " value: " ..
tostring(self.org.modules[mod_choice][policy_choice]) tostring(modpol.modules[mod_choice][policy_choice])
.. "\nChange value to:", .. "\nChange value to (be careful!):",
function(policy_input) function(policy_input)
self:approve_change( self:approve_change(
mod_choice, mod_choice,
@ -99,7 +99,7 @@ function change_policy:approve_change(module_slug, policy, input)
self.initiator, self.initiator,
"Updating " .. policy .. " policy on module " .. "Updating " .. policy .. " policy on module " ..
module_slug .. " with: " .. input) module_slug .. " with: " .. input)
self.org.modules[module_slug].config[policy] = input self.org.policies[module_slug][policy] = input
modpol.interactions.org_dashboard( modpol.interactions.org_dashboard(
self.initiator, self.org.id) self.initiator, self.org.id)
if self.data.result then self.data.result() end if self.data.result then self.data.result() end

View File

@ -19,26 +19,30 @@ display_policies.config = {
-- @param result Callback if this module is embedded in other modules -- @param result Callback if this module is embedded in other modules
function display_policies:initiate(result) function display_policies:initiate(result)
local display_table = {} local display_table = {}
for k,v in pairs(self.org.modules) do for k,v in pairs(self.org.policies) do
local input = v.name if v then -- check the module is allowed
table.insert(display_table, input) local input = modpol.modules[k].name
if v.config table.insert(display_table, input)
and modpol.util.num_pairs(v.config) > 0 then if modpol.modules[k].config then
for k2,v2 in pairs(v.config) do for k2,v2 in pairs(modpol.modules[k].config) do
local v2_string = "" if self.org.policies[k][k2] then
if type(v2) == "string" then v2 = self.org.policies[k][k2]
v2_string = v2 end
elseif type(v2) == "table" local v2_string = ""
or type(v2) == "number" then if type(v2) == "string" then
v2_string = tostring(v2) v2_string = v2
else elseif type(v2) == "table"
v2_string = "Could not render" or type(v2) == "number" then
v2_string = tostring(v2)
else
v2_string = "Could not render"
end
input = k2..": "..v2_string
table.insert(display_table, input)
end end
input = k2..": "..v2_string
table.insert(display_table, input)
end end
table.insert(display_table, "---")
end end
table.insert(display_table, "---")
end end
local output = table.concat(display_table,"\n") local output = table.concat(display_table,"\n")
if #display_table == 0 then if #display_table == 0 then

View File

@ -14,7 +14,7 @@ function temp_org()
return { return {
id = nil, id = nil,
name = nil, name = nil,
modules = modpol.util.copy_table(modpol.modules), policies = {},
processes = {}, processes = {},
pending = {}, pending = {},
members = {}, members = {},
@ -105,6 +105,9 @@ function modpol.orgs.init_instance()
local instance = temp_org() local instance = temp_org()
instance.id = 1 instance.id = 1
instance.name = "Root" instance.name = "Root"
for i,v in pairs(modpol.modules) do
instance.policies[i] = {}
end
setmetatable(instance, modpol.orgs) setmetatable(instance, modpol.orgs)
@ -183,7 +186,7 @@ function modpol.orgs:add_org(name, user)
child_org.name = name child_org.name = name
child_org.parent = self.id child_org.parent = self.id
child_org.processes = {} child_org.processes = {}
child_org.modules = modpol.util.copy_table(self.modules) child_org.policies = modpol.util.copy_table(self.policies)
setmetatable(child_org, modpol.orgs) setmetatable(child_org, modpol.orgs)

View File

@ -15,7 +15,7 @@ function modpol.orgs:call_module(module_slug, initiator, config, result, parent_
local index = #self.processes + 1 local index = #self.processes + 1
local module = self.modules[module_slug] local module = modpol.modules[module_slug]
-- first applies any relevant org policies -- first applies any relevant org policies
-- then overrides with the config values given on input -- then overrides with the config values given on input
@ -23,6 +23,11 @@ function modpol.orgs:call_module(module_slug, initiator, config, result, parent_
if modpol.util.num_pairs(module.config) > 0 then if modpol.util.num_pairs(module.config) > 0 then
for k, v in pairs(module.config) do for k, v in pairs(module.config) do
new_config[k] = v new_config[k] = v
-- overrides with org policies
if self.policies[module_slug]
and self.policies[module_slug][k] then
new_config[k] = self.policies[module_slug][k]
end
-- overrides with input settings -- overrides with input settings
if config and config[k] then if config and config[k] then
new_config[k] = config[k] new_config[k] = config[k]

View File

@ -145,9 +145,10 @@ function modpol.interactions.org_dashboard(user, org_string)
-- prepare modules menu -- prepare modules menu
local modules = {} local modules = {}
if org.modules then if modpol.modules then
for k,v in pairs(org.modules) do for k,v in pairs(modpol.modules) do
if not v.hide then -- hide utility modules if not v.hide and -- hide utility modules
org.policies[k] then -- org includes it
local module_entry = v.name local module_entry = v.name
table.insert(modules, module_entry) table.insert(modules, module_entry)
end end
@ -228,8 +229,9 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
elseif fields.modules elseif fields.modules
and fields.modules ~= "View..." then and fields.modules ~= "View..." then
local module = nil local module = nil
for k,v in pairs(org.modules) do for k,v in pairs(modpol.modules) do
if fields.modules == v.name then if fields.modules == v.name
and org.policies[v.slug] then
module = v module = v
end end end end
if module then if module then
@ -411,10 +413,10 @@ function modpol.interactions.text_query(user, query, func)
-- set up formspec -- set up formspec
local formspec = { local formspec = {
"formspec_version[4]", "formspec_version[4]",
"size[10,4]", "size[10,6]",
"label[0.5,1;", minetest.formspec_escape(query), "]", "label[0.5,1;", minetest.formspec_escape(query), "]",
"field[0.5,1.25;9,0.8;input;;]", "field[0.5,3.25;9,0.8;input;;]",
"button[0.5,2.5;1,0.8;yes;OK]", "button[0.5,4.5;1,0.8;yes;OK]",
} }
local formspec_string = table.concat(formspec, "") local formspec_string = table.concat(formspec, "")
-- present to player -- present to player