321 lines
9.2 KiB
Lua
321 lines
9.2 KiB
Lua
--- Orgs: Base
|
|
-- Basic functions for orgs
|
|
|
|
modpol.orgs = modpol.orgs or
|
|
{
|
|
count = 1,
|
|
array = {}
|
|
}
|
|
|
|
-- sets modpol.orgs as its own fallback
|
|
modpol.orgs.__index = modpol.orgs
|
|
|
|
function temp_org()
|
|
return {
|
|
id = nil,
|
|
name = nil,
|
|
modules = modpol.util.copy_table(modpol.modules),
|
|
processes = {},
|
|
pending = {},
|
|
members = {},
|
|
parent = nil,
|
|
children = {}
|
|
}
|
|
end
|
|
|
|
-- ==================================================
|
|
-- returns org when given its id or name
|
|
function modpol.orgs.get_org(arg)
|
|
if type(arg) == 'string' then
|
|
for id, org in ipairs(modpol.orgs.array) do
|
|
if org.name == arg then
|
|
return org
|
|
end
|
|
end
|
|
elseif type(arg) == 'number' then
|
|
return modpol.orgs.array[arg]
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- ===============================================
|
|
-- returns a table list of all org names
|
|
function modpol.orgs.list_all()
|
|
local org_table
|
|
for k, v in ipairs(modpol.orgs.array) do
|
|
if type(v) == 'table' then
|
|
if org_table then
|
|
table.insert(org_table, v.name)
|
|
else
|
|
org_table = {v.name}
|
|
end
|
|
end
|
|
end
|
|
return org_table
|
|
end
|
|
|
|
-- Function: modpol.orgs.user_orgs(user)
|
|
-- input: user (string)
|
|
-- output: table of strings of org names
|
|
function modpol.orgs.user_orgs(user)
|
|
local all_orgs = modpol.orgs.list_all()
|
|
local user_orgs = {}
|
|
for i,v in ipairs(all_orgs) do
|
|
local this_table = modpol.orgs.get_org(v)
|
|
if this_table:has_member(user) then
|
|
table.insert(user_orgs,v)
|
|
end
|
|
end
|
|
return user_orgs
|
|
end
|
|
|
|
-- ===========================================
|
|
-- deletes all orgs except for the instance
|
|
function modpol.orgs.reset()
|
|
local instance_members =
|
|
modpol.util.copy_table(modpol.instance.members)
|
|
for id, org in ipairs(modpol.orgs.array) do
|
|
if id > 1 then
|
|
modpol.orgs.array[id] = "removed"
|
|
end
|
|
end
|
|
|
|
modpol.orgs.array[1] = nil
|
|
modpol.instance = modpol.orgs.init_instance()
|
|
modpol.instance.members = instance_members
|
|
|
|
modpol.ocutil.log('All orgs reset')
|
|
modpol.orgs:record('Resetting all orgs', 'org_reset')
|
|
end
|
|
|
|
-- ===================================================
|
|
-- initializes the instance (root org)
|
|
-- can only be run once, as only one instance can exist
|
|
function modpol.orgs.init_instance()
|
|
local error_msg
|
|
if modpol.orgs.array[1] then
|
|
modpol.ocutil.log('Error in orgs.init_instance -> instance has already been initialized')
|
|
return false
|
|
end
|
|
|
|
local instance = temp_org()
|
|
instance.id = 1
|
|
instance.name = "Root"
|
|
|
|
setmetatable(instance, modpol.orgs)
|
|
|
|
-- adding instance to org list
|
|
modpol.orgs.array[1] = instance
|
|
|
|
modpol.ocutil.log('Initialized the instance root org')
|
|
modpol.orgs:record('Initialized the instance root org', 'create_instance')
|
|
|
|
return instance
|
|
end
|
|
|
|
|
|
-- FUNCTIONS BEYOND HERE OPERATE ON ORG OBJECTS
|
|
|
|
-- =======================================================
|
|
-- records a log message to the modpol ledger
|
|
function modpol.orgs:record(msg, entry_type)
|
|
local entry = {
|
|
timestamp = '',
|
|
entry_type = nil,
|
|
action_msg = '',
|
|
org_name = '',
|
|
org_id = nil,
|
|
}
|
|
|
|
if type(msg) == 'string' and not(modpol.ocutil.str_empty(msg)) then
|
|
entry.action_msg = msg
|
|
else
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':record -> msg must be a non empty string')
|
|
return false
|
|
end
|
|
|
|
if type(entry_type) == 'string' and not(modpol.ocutil.str_empty(entry_type)) then
|
|
entry.entry_type = entry_type
|
|
else
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':record -> entry_type must be a non empty string')
|
|
modpol.ocutil.log(msg, entry_type)
|
|
return false
|
|
end
|
|
|
|
entry.timestamp = os.time()
|
|
entry.org_id = self.id
|
|
entry.org_name = self.name
|
|
|
|
table.insert(modpol.ledger, entry)
|
|
modpol.store_data()
|
|
end
|
|
|
|
-- ==================================================
|
|
-- adds a new sub org to the org it is called on
|
|
-- input: name (string), user (string)
|
|
-- ex: instance:add_org('town hall')
|
|
function modpol.orgs:add_org(name, user)
|
|
if self.id == nil then
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':add_org -> add_org can only be called by another org')
|
|
return false
|
|
end
|
|
|
|
if modpol.ocutil.str_empty(name) then
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':add_org -> org name is required')
|
|
return false
|
|
end
|
|
|
|
if modpol.orgs.get_org(name) then
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':add_org -> org name is already being used')
|
|
return false
|
|
end
|
|
|
|
-- creating the child sub org
|
|
modpol.orgs.count = modpol.orgs.count + 1
|
|
local child_org = temp_org()
|
|
child_org.id = modpol.orgs.count
|
|
child_org.name = name
|
|
child_org.parent = self.id
|
|
child_org.processes = {}
|
|
child_org.modules = modpol.util.copy_table(self.modules)
|
|
|
|
setmetatable(child_org, modpol.orgs)
|
|
|
|
-- adding child id to list of children
|
|
table.insert(self.children, child_org.id)
|
|
|
|
-- adding child to org list
|
|
modpol.orgs.array[child_org.id] = child_org
|
|
|
|
-- adding creator of org as the first member
|
|
child_org:add_member(user)
|
|
|
|
self:record('created sub org ' .. name, 'add_org')
|
|
modpol.ocutil.log('Created ' .. name .. ' (suborg of ' .. self.name .. ')')
|
|
|
|
return child_org
|
|
end
|
|
|
|
-- ========================================
|
|
-- recursively deletes an org and its suborgs
|
|
-- leaves entry in modpol.orgs.array as a string "removed"
|
|
-- note: "reason" param was removed, can be added back
|
|
function modpol.orgs:delete()
|
|
if self.id == 1 then
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':delete -> cannot delete instance')
|
|
return false
|
|
end
|
|
|
|
if #self.children > 0 then
|
|
for i, child_id in pairs(self.children) do
|
|
local child = modpol.orgs.get_org(child_id)
|
|
modpol.ocutil.log(child_id, child)
|
|
child:delete()
|
|
end
|
|
end
|
|
|
|
modpol.orgs.array[self.id] = 'removed'
|
|
modpol.ocutil.log('Deleted org ' .. self.name .. ': ' .. self.id)
|
|
|
|
self:record('Deleted ' .. self.name .. ' and all child orgs', 'del_org')
|
|
|
|
end
|
|
|
|
|
|
-- ===========================================
|
|
-- internal function to get the index of a member name
|
|
function modpol.orgs:get_member_index(member)
|
|
for k, v in ipairs(self.members) do
|
|
if v == member then
|
|
return k
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ===========================================
|
|
-- adds a user to an org
|
|
function modpol.orgs:add_member(user)
|
|
for id, name in ipairs(self.members) do
|
|
if user == name then
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':add_member -> user already in org')
|
|
return false
|
|
end
|
|
end
|
|
-- trys to fill in empty spots first
|
|
local empty_index = self:get_member_index('')
|
|
if empty_index then
|
|
self.members[empty_index] = user
|
|
else
|
|
-- adds to end if no empty spots
|
|
table.insert(self.members, user)
|
|
end
|
|
|
|
modpol.ocutil.log('Added member ' .. user .. ' to ' .. self.name)
|
|
self:record('Added member ' .. user, 'add_member')
|
|
|
|
end
|
|
|
|
-- =======================================
|
|
-- removes a user from an org
|
|
function modpol.orgs:remove_member(user)
|
|
-- sets the array index to an empty string so that consecutive list is preserved
|
|
-- empty spots will get filled in by new members
|
|
local user_index = self:get_member_index(user)
|
|
if user_index then
|
|
self.members[user_index] = ''
|
|
else
|
|
modpol.ocutil.log('Error in ' .. self.name .. ':remove_member -> user not in org')
|
|
end
|
|
modpol.ocutil.log('Removed member ' .. user .. ' from ' .. self.name)
|
|
self:record('Removed member ' .. user, 'del_member')
|
|
end
|
|
|
|
-- ===========================================
|
|
-- boolean check whether user is an org
|
|
function modpol.orgs:has_member(user)
|
|
local user_index = self:get_member_index(user)
|
|
if user_index then
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- ==================================
|
|
-- Function: modpol.orgs:list_members()
|
|
-- output: a table of the names (string) of members
|
|
function modpol.orgs:list_members()
|
|
local members = {}
|
|
for k, v in ipairs(self.members) do
|
|
table.insert(members, v)
|
|
end
|
|
return members
|
|
end
|
|
|
|
-- ==============================
|
|
-- because member list uses lazy deletion, using #org.members will not show an accurate number
|
|
function modpol.orgs:get_member_count()
|
|
local count = 0
|
|
for k, v in ipairs(self.members) do
|
|
-- the empty string represents a deleted member in the members list
|
|
if v ~= '' then
|
|
count = count + 1
|
|
end
|
|
end
|
|
return count
|
|
end
|
|
-- ====================================
|
|
-- adds a new policy to the policy table
|
|
-- must define the policy type, process associated with it, and whether the request must be made by an org member
|
|
function modpol.orgs:set_policy(policy_type, process_type, must_be_member)
|
|
local new_policy = {
|
|
process_type = process_type,
|
|
must_be_member = must_be_member
|
|
}
|
|
self.policies[policy_type] = new_policy
|
|
modpol.ocutil.log('Added policy for ' .. policy_type .. ' in ' .. self.name)
|
|
self:record('Added policy for ' .. policy_type, 'set_policy')
|
|
end
|
|
|
|
|