core_algorithm.alc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. include "modelling.alh"
  2. include "library.alh"
  3. Element core = ?
  4. Void function main():
  5. // Initialize the Core Formalism
  6. String core_location
  7. String admin_group
  8. String admin_user
  9. core_location = "models/CoreFormalism"
  10. // Create the Model itself and make public
  11. core = instantiate_model(import_node(core_location))
  12. // Create admin group
  13. admin_group = instantiate_node(core, "Group", "")
  14. instantiate_attribute(core, admin_group, "name", "admin")
  15. // Create admin user
  16. admin_user = instantiate_node(core, "User", "")
  17. instantiate_attribute(core, admin_user, "name", get_username())
  18. instantiate_attribute(core, admin_user, "admin", True)
  19. // Create link between admin user and group
  20. instantiate_link(core, "ownedBy", "", admin_group, admin_user)
  21. instantiate_link(core, "belongsTo", "", admin_user, admin_group)
  22. // Add the core formalism already
  23. core_model = instantiate_node(core, "Model", "")
  24. instantiate_attribute(core, core_model, "name", "CoreFormalism")
  25. instantiate_attribute(core, core_model, "location", core_location)
  26. instantiate_attribute(core, core_model, "permissions", "330")
  27. // Make necessary links for the formalism to the owners
  28. instantiate_link(core, "group", "", core_model, admin_group)
  29. instantiate_link(core, "owner", "", core_model, admin_user)
  30. // Switch all new users to the user_function
  31. // This accesses the bootstrap level, so do not change this unless you know what you are doing
  32. Element root
  33. root = read_root()
  34. dict_del(root["__hierarchy"], "__IP")
  35. dict_add(root["__hierarchy"], "__IP", user_function)
  36. // Call this for ourselves as well
  37. user_function_skip_init(admin_user)
  38. // Done, so finish up
  39. // Admin user will have been deleted by the user_function as usual
  40. // Note that if there are no admin users left, it will be very difficult to manage, as nobody will have admin permissions!
  41. return !
  42. Integer function get_relation_to_model(user_id : String, model_id : String):
  43. if (set_in(allAssociationDestinations(core, model_id, "owner"), user_id)):
  44. // We are the owner
  45. return 0!
  46. else:
  47. String group_id
  48. group_id = set_pop(allAssociationDestinations(core, model_id, "group"))
  49. if (set_in(allAssociationDestinations(core, user_id, "belongsTo"), group_id)):
  50. // We are in the owning group
  51. return 1!
  52. else:
  53. // We are not related whatsoever
  54. return 2!
  55. Boolean function is_admin(user_id : String):
  56. if (read_attribute(core, user_id, "admin")):
  57. return True!
  58. else:
  59. return False!
  60. Boolean function allow_read(user_id : String, model_id : String):
  61. if (is_admin(user_id)):
  62. // Is admin, so always allow
  63. return True!
  64. else:
  65. // Check permissions
  66. String permission
  67. permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id))
  68. if (bool_or(permission == "1", permission == "3")):
  69. return True!
  70. else:
  71. return False!
  72. Boolean function allow_write(user_id : String, model_id : String):
  73. if (is_admin(user_id)):
  74. // Is admin, so always allow
  75. return True!
  76. else:
  77. // Check permissions
  78. String permission
  79. permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id))
  80. if (bool_or(permission == "2", permission == "3")):
  81. return True!
  82. else:
  83. return False!
  84. Boolean function allow_change_metadata(user_id : String, model_id : String):
  85. if (is_admin(user_id)):
  86. // Is admin, so always allow
  87. return True!
  88. else:
  89. if (get_relation_to_model(user_id, model_id) == "0"):
  90. // Only owner can chmod
  91. return True!
  92. else:
  93. return False!
  94. Void function user_function():
  95. // Now the username is bound to the task ID, so there is no problem
  96. // TODO check whether username isn't registered yet
  97. // Add user to Core Formalism
  98. String user_id
  99. user_id = instantiate_node(core, "User", "")
  100. instantiate_attribute(core, user_id, "name", get_username())
  101. instantiate_attribute(core, user_id, "admin", False)
  102. // Now call with user created
  103. user_function_skip_init(user_id)
  104. // User destroyed already, so just stop execution
  105. return !
  106. String function get_model_id(name : String):
  107. Element models
  108. String model
  109. models = allInstances(core, "Model")
  110. while (read_nr_out(models) > 0):
  111. model = set_pop(models)
  112. if (read_attribute(core, model, "name") == name):
  113. return model!
  114. return ""!
  115. Void function user_function_skip_init(user_id : String)
  116. Boolean do_continue
  117. String cmd
  118. do_continue = True
  119. output("Welcome to the Model Management Interface v2.0!")
  120. output("Use the 'help' command for a list of possible commands")
  121. while (do_continue):
  122. output("Ready for command...")
  123. cmd = input()
  124. if (cmd == "help"):
  125. output("Model operations")
  126. output(" model_add -- Add a new model")
  127. output(" model_modify -- Modify an existing model")
  128. output(" model_delete -- [TODO] Delete a model and all related transformations")
  129. output(" model_list -- List all models")
  130. output(" model_list_full -- List all models with full info")
  131. output("")
  132. output("Transformation-specific operations")
  133. output(" transformation_add -- TODO")
  134. output(" transformation_source_add -- TODO")
  135. output(" transformation_source_delete -- TODO")
  136. output(" transformation_target_add -- TODO")
  137. output(" transformation_target_delete -- TODO")
  138. output(" transformation_execute -- TODO")
  139. output("")
  140. output("Model permission operations")
  141. output(" permission_modify -- TODO")
  142. output(" permission_owner -- TODO")
  143. output(" permission_group -- TODO")
  144. output("")
  145. output("Group operations")
  146. output(" group_create -- TODO")
  147. output(" group_delete -- TODO")
  148. output(" group_owner -- Change group owner")
  149. output(" group_join -- Add someone to your group")
  150. output(" group_kick -- Kick someone from your group")
  151. output(" group_list -- List all groups you are a member of")
  152. output("")
  153. output("Admin operations")
  154. output(" admin_promote -- Promote a user to admin status")
  155. output(" admin_demote -- Demote a user to normal status")
  156. output("")
  157. output("General operations")
  158. output(" account_delete -- Remove current user and revoke all permissions ")
  159. elif (cmd == "model_add"):
  160. // Model addition operation, which uses model upload commands of the compiler
  161. String name
  162. String type
  163. String location
  164. Element new_model
  165. output("Creating new model!")
  166. output("Model type?")
  167. type_id = get_model_id(input())
  168. if (type_id != ""):
  169. // Type exists
  170. if (allow_read(user_id, type_id)):
  171. // And is readable
  172. output("Model name?")
  173. name = input()
  174. if (get_model_id(name) == ""):
  175. // Model doesn't exist yet
  176. output("Waiting for model constructors...")
  177. // TODO update for access control
  178. new_model = construct_model(read_attribute(core, type_id, "location"))
  179. output("Model upload success!")
  180. location = "/models/" + cast_id2s(new_model)
  181. export_node(new_model, location)
  182. // Manage meta-info
  183. new_model_id = instantiate_node(core, "Model", "")
  184. instantiate_attribute(core, new_model_id, "name", name)
  185. instantiate_attribute(core, new_model_id, "location", location)
  186. instantiate_attribute(core, new_model_id, "permissions", "300")
  187. instantiate_link(core, "owner", "", new_model_id, user_id)
  188. instantiate_link(core, "instanceOf", "", new_model_id, type_id)
  189. output("Meta-info correctly set!")
  190. else:
  191. output("Model with that name already exists!")
  192. else:
  193. output("You are not allowed to read this type model!")
  194. else:
  195. output("Could not find type model!")
  196. elif (cmd == "model_modify"):
  197. // Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control
  198. String model_id
  199. output("Which model do you want to modify?")
  200. model_id = get_model_id(input())
  201. if (model_id != ""):
  202. if (allow_read(user_id, model_id)):
  203. mini_modify(import_node(read_attribute(core, model_id, "location")), allow_write(user_id, model_id))
  204. else:
  205. output("You are not allowed to read this model!")
  206. else:
  207. output("Could not find model!")
  208. elif (cmd == "model_delete"):
  209. // Delete a model and all of its related transformations
  210. String model_id
  211. output("=================================================")
  212. output("WARNING: Deletion is a very destructive operation")
  213. output(" as it also deletes all transformations ")
  214. output(" defined which make use of this model! ")
  215. output("=================================================")
  216. output("")
  217. output("Currently not supported!")
  218. elif (cmd == "model_list"):
  219. // List all models
  220. Element models
  221. String m
  222. models = allInstances(core, "Model")
  223. while (read_nr_out(models) > 0):
  224. m = set_pop(models)
  225. output((" " + (read_attribute(core, m, "name")) + " : ") + read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name"))
  226. elif (cmd == "model_list_full")
  227. // List all models with full info
  228. Element models
  229. String m
  230. String permissions
  231. String owner
  232. String group
  233. String name
  234. String type
  235. models = allInstances(core, "Model")
  236. while (read_nr_out(models) > 0):
  237. m = set_pop(models)
  238. permissions = read_attribute(core, m, "permissions")
  239. owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
  240. group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
  241. name = read_attribute(core, m, "name")
  242. size = read_nr_out(dict_read(import_node(read_attribute(core, m, "location")), "model"))
  243. type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
  244. output(((((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + size) + " ") + name) + " : ") + type)
  245. elif (cmd == "group_join"):
  246. // Add someone to your group
  247. String group_id
  248. output("Which group do you want to add someone to?")
  249. group_id = get_group_id(input())
  250. if (group_id != ""):
  251. if (allow_group_modify(user_id, group_id)):
  252. output("Which user do you want to add?")
  253. other_user_id = get_user_id(input())
  254. if (other_user_id != ""):
  255. Element overlap
  256. overlap = set_overlap(allOutgoingAssociationInstances(core, user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  257. if (read_nr_out(overlap) == 0):
  258. instantiate_link(core, "belongsTo", "", user_id, group_id)
  259. output("User added to the group!")
  260. else:
  261. output("User is already a member of the group!")
  262. else:
  263. output("No such user")
  264. else:
  265. output("Permission denied!")
  266. else:
  267. output("No such group")
  268. elif (cmd == "group_kick"):
  269. // Remove someone from your group
  270. String group_id
  271. output("Which group do you want to kick someone from?")
  272. group_id = get_group_id(input())
  273. if (group_id != ""):
  274. if (allow_group_modify(user_id, group_id)):
  275. output("Which user do you want to kick?")
  276. other_user_id = get_user_id(input())
  277. if (other_user_id != ""):
  278. Element overlap
  279. overlap = set_overlap(allOutgoingAssociationInstances(core, user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  280. if (read_nr_out(overlap) > 0):
  281. model_delete_element(core, set_pop(overlap))
  282. // Check if user was an owner as well
  283. overlap = set_overlap(allIncomingAssociationInstances(core, user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  284. if (read_nr_out(overlap) > 0):
  285. model_delete_element(core, set_pop(overlap))
  286. output("User kicked!")
  287. else:
  288. output("User is not even a member of the group!")
  289. else:
  290. output("No such user")
  291. else:
  292. output("Permission denied!")
  293. else:
  294. output("No such group")
  295. elif (cmd == "group_list"):
  296. // List all groups you are a member of (and whether you are admin or not!)
  297. Element groups
  298. String group_id
  299. String admin
  300. groups = allAssociationDestinations(core, user_id, "belongsTo")
  301. while (True):
  302. group_id = set_pop(groups)
  303. if (set_in(allAssociation(core, group_id, "owner"), user_id)):
  304. admin = " A "
  305. else:
  306. admin = " "
  307. output(admin + read_attribute(core, group_id, "name"))
  308. elif (cmd == "admin_promote"):
  309. // Promote a user to admin status
  310. if (is_admin(user_id)):
  311. String other_user_id
  312. output("Which user do you want to promote?")
  313. other_user_id = get_user_id(input())
  314. if (other_user_id != ""):
  315. unset_attribute(core, other_user_id, "admin")
  316. instantiate_attribute(core, other_user_id, "admin", True)
  317. output("Permissions granted!")
  318. else:
  319. output("No such user!")
  320. else:
  321. output("Permission denied!")
  322. elif (cmd == "admin_demote"):
  323. // Demote a user to normal status
  324. if (is_admin(user_id)):
  325. String other_user_id
  326. output("Which user do you want to demote?")
  327. other_user_id = get_user_id(input())
  328. if (other_user_id != ""):
  329. unset_attribute(core, other_user_id, "admin")
  330. instantiate_attribute(core, other_user_id, "admin", False)
  331. output("Permissions revoked!")
  332. else:
  333. output("No such user!")
  334. else:
  335. output("Permission denied!")
  336. elif (cmd == "exit"):
  337. // Exit by actually removing the user and decoupling it from all of its models
  338. // Restarting with the same user name will NOT grant you access to anything of the previous user with that same name
  339. do_continue = False
  340. // Delete user from Core Formalism
  341. model_delete_element(core, user_id)
  342. output("Goodbye!")
  343. return !