modpol.orgs = { count = 1, array = {} } -- sets modpol.orgs as it's own fallback modpol.orgs.__index = modpol.orgs -- ================================================== -- 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 string list of all orgs function modpol.orgs.list_all() local str for k, v in ipairs(modpol.orgs.array) do if type(v) == 'table' then if str then str = str .. '\n' .. v.name else str = v.name end end end return str end -- =========================================== -- deletes all orgs except for the instance function modpol.orgs.reset() for id, org in ipairs(modpol.orgs.array) do if id > 1 then modpol.orgs.array[id] = nil end end 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 error_msg = 'Error: instance has already been initialized' modpol.ocutil.log(error_msg) return false, error_msg end local instance = { id = 1, name = "instance", policies = {}, members = {}, ledger = {}, parent = nil, children = {}, properties = {}, old_names = {} } setmetatable(instance, modpol.orgs) -- adding instance to org list modpol.orgs.array[1] = 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 print('Error: 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 print('Error: entry_type must be a non empty string') 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 -- ex: instance:add_org('town hall') function modpol.orgs:add_org(name) if self.id == nil then error_msg = 'Error: add_org can only be called by another org' modpol.ocutil.log(error_msg) return false, error_msg end if modpol.ocutil.str_empty(name) then error_msg = 'Error: org name is required' modpol.ocutil.log(error_msg) return false, error_msg end -- creating the child sub org modpol.orgs.count = modpol.orgs.count + 1 local child_org = { id = modpol.orgs.count, name = name, policies = {}, members = {}, parent = self.id, children = {}, } 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 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 return false, 'Error: cannot delete instance' end if #self.children > 0 then for i, child_id in pairs(self.children) do local child = modpol.orgs.get_org(child_id) print(child_id, child) child:delete() end end modpol.orgs.array[self.id] = 'removed' print('Removed ' .. self.name .. ': ' .. self.id) 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) -- trys to fill in empty spots first 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 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 user_index = self:get_member_index(user) if user_index then self.members[user_index] = '' end end -- =========================================== -- boolean check whether user is an org function modpol.orgs:has_member(user) user_index = self:get_member_index(user) if user_index then return true else return false end end -- ================================== -- returns a list of users in an org function modpol.orgs:list_member() local str for k, v in ipairs(self.members) do if str then str = str .. '\n' .. v else str = v end end return str end