requests.lua 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. modpol.orgs.request_params = {
  2. add_org = 1,
  3. delete = 0,
  4. add_member = 1,
  5. remove_member = 1
  6. }
  7. -- ================================
  8. -- creates a new process linked to a request id
  9. function modpol.orgs:create_process(process_type, request_id)
  10. if not modpol.modules[process_type] then
  11. modpol.ocutil.log('Process type "' .. process_type .. '" does not exist')
  12. return
  13. end
  14. -- retrieving requested module
  15. local module = modpol.modules[process_type]
  16. local new_process = module:new_process(request_id, self.id)
  17. -- linear search for empty process slots (lazy deletion)
  18. for k, v in ipairs(self.processes) do
  19. if v == 'deleted' then
  20. local empty_index = k
  21. break
  22. end
  23. end
  24. local index
  25. -- attempts to fill empty spots in list, otherwise appends to end
  26. if empty_index then
  27. self.processes[empty_index] = new_process
  28. index = empty_index
  29. else
  30. table.insert(self.processes, new_process)
  31. index = #self.processes
  32. end
  33. new_process.id = index
  34. return index
  35. end
  36. -- ===========================
  37. -- compares to requests to see if they are identical
  38. function modpol.orgs.comp_req(req1, req2)
  39. -- compares request type
  40. if req1.type ~= req2.type then
  41. return false
  42. else
  43. -- comparing parameters
  44. -- we can assume the number of params is the same as this is checked in the make_request func
  45. for k, v in ipairs(req1.params) do
  46. if v ~= req2.params[k] then
  47. return false
  48. end
  49. end
  50. end
  51. return true
  52. end
  53. -- ===============================
  54. -- returns string of all active requests
  55. function modpol.orgs:list_request()
  56. local str
  57. for id, req in ipairs(self.requests) do
  58. if req ~= "deleted" then
  59. if str then
  60. str = str .. '\n' .. req.type .. ' (' .. req.user .. ') '
  61. else
  62. str = req.type .. ' (' .. req.user .. ') '
  63. end
  64. end
  65. end
  66. return str
  67. end
  68. -- ===============================
  69. -- if the request was approved, the associated function is called, otherwise it is deleted
  70. function modpol.orgs:resolve_request(request_id, approve)
  71. if approve then
  72. local request = self.requests[request_id]
  73. local p = request.params
  74. -- there's probably a way to clean this up, the issue is the varying number of commands
  75. -- ex: self['add_member'](self, 'member_name')
  76. -- not sure if this is safe, more testing to do
  77. -- self[request.type](self, p[1], p[2], p[3])
  78. if request.type == "add_org" then
  79. self:add_org(request.params[1], request.user)
  80. elseif request.type == "delete" then
  81. self:delete()
  82. elseif request.type == "add_member" then
  83. self:add_member(request.params[1])
  84. elseif request.type == "remove_member" then
  85. self:remove_member(request.params[1])
  86. end
  87. end
  88. self.requests[request_id] = "deleted"
  89. end
  90. -- ================================
  91. -- tries to make a request to the org
  92. function modpol.orgs:make_request(request)
  93. -- makes sure the request has the valid number of parameters
  94. local num_params = modpol.orgs.request_params[request.type]
  95. if num_params == nil then
  96. modpol.ocutil.log('Error in ' .. self.name .. ':make_request -> request type is invalid')
  97. return false
  98. end
  99. -- request.params should match the num of params for that type
  100. if #request.params ~= num_params then
  101. modpol.ocutil.log('Error in ' .. self.name .. ':make_request -> request has invalid number of parameters')
  102. return false
  103. end
  104. -- checking to see if identical request already exists
  105. for k, v in ipairs(self.requests) do
  106. if self.comp_req(request, v) == true then
  107. modpol.ocutil.log('Error in ' .. self.name .. ':make_request -> request has already been made')
  108. return false
  109. end
  110. end
  111. -- checking to see if user is able to make request
  112. local requested_policy = self.policies[request.type]
  113. -- if not the instance org (instance's don't have parents)
  114. if self.id ~= 1 then
  115. local parent_policy = modpol.orgs.get_org(self.parent).policies[request.type]
  116. -- tries to use org's policy table, defers to parent otherwise
  117. if not requested_policy then
  118. modpol.ocutil.log(request.type .. ' policy not found, deferring to parent org')
  119. requested_policy = parent_policy
  120. if not parent_policy then
  121. modpol.ocutil.log('Error in ' .. self.name .. ':make_request -> parent policy undefined')
  122. return false
  123. end
  124. end
  125. -- fails if instance policy undefined
  126. else
  127. if not requested_policy then
  128. modpol.ocutil.log('Error in ' .. self.name .. ':make_request -> policy undefined')
  129. return false
  130. end
  131. end
  132. -- make sure user is allowed to make request
  133. if requested_policy.must_be_member and not self:has_member(request.user) then
  134. modpol.ocutil.log('Error in ' .. self.name .. ':make_request -> user must be org member to make this request')
  135. return false
  136. end
  137. -- linear search for empty process slots (lazy deletion)
  138. for k, v in ipairs(self.requests) do
  139. if v == 'deleted' then
  140. local empty_index = k
  141. break
  142. end
  143. end
  144. -- attempts to fill empty spots in list, otherwise appends to end
  145. local request_id = nil
  146. if empty_index then
  147. self.requests[empty_index] = request
  148. request_id = empty_index
  149. else
  150. table.insert(self.requests, request)
  151. request_id = #self.requests
  152. end
  153. modpol.ocutil.log("Request made by " .. request.user .. " to " .. request.type)
  154. -- launching process tied to this request
  155. local process_id = self:create_process(requested_policy.process_type, request_id)
  156. -- returns process id of processes launched by this request
  157. return process_id
  158. end