core_algorithm.alc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  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", "220")
  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 == "2")):
  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 (permission == "2"):
  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 -- Change model permissions")
  142. output(" permission_owner -- Change model owner")
  143. output(" permission_group -- Change model group")
  144. output("")
  145. output("Group operations")
  146. output(" group_create -- Create a group"))
  147. output(" group_delete -- Delete a group")
  148. output(" group_owner_add -- Add group owner")
  149. output(" group_owner_delete -- Remove group owner")
  150. output(" group_join -- Add someone to your group")
  151. output(" group_kick -- Kick someone from your group")
  152. output(" group_list -- List all groups you are a member of")
  153. output("")
  154. output("Admin operations")
  155. output(" admin_promote -- Promote a user to admin status")
  156. output(" admin_demote -- Demote a user to normal status")
  157. output("")
  158. output("General operations")
  159. output(" account_delete -- Remove current user and revoke all permissions ")
  160. elif (cmd == "model_add"):
  161. // Model addition operation, which uses model upload commands of the compiler
  162. String name
  163. String type
  164. String location
  165. Element new_model
  166. output("Creating new model!")
  167. output("Model type?")
  168. type_id = get_model_id(input())
  169. if (type_id != ""):
  170. // Type exists
  171. if (allow_read(user_id, type_id)):
  172. // And is readable
  173. output("Model name?")
  174. name = input()
  175. if (get_model_id(name) == ""):
  176. // Model doesn't exist yet
  177. output("Waiting for model constructors...")
  178. // TODO update for access control
  179. new_model = construct_model(read_attribute(core, type_id, "location"))
  180. output("Model upload success!")
  181. location = "/models/" + cast_id2s(new_model)
  182. export_node(new_model, location)
  183. // Manage meta-info
  184. new_model_id = instantiate_node(core, "Model", "")
  185. instantiate_attribute(core, new_model_id, "name", name)
  186. instantiate_attribute(core, new_model_id, "location", location)
  187. instantiate_attribute(core, new_model_id, "permissions", "200")
  188. instantiate_link(core, "owner", "", new_model_id, user_id)
  189. instantiate_link(core, "instanceOf", "", new_model_id, type_id)
  190. output("Meta-info correctly set!")
  191. else:
  192. output("Model with that name already exists!")
  193. else:
  194. output("You are not allowed to read this type model!")
  195. else:
  196. output("Could not find type model!")
  197. elif (cmd == "model_modify"):
  198. // Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control
  199. String model_id
  200. output("Which model do you want to modify?")
  201. model_id = get_model_id(input())
  202. if (model_id != ""):
  203. if (allow_read(user_id, model_id)):
  204. mini_modify(import_node(read_attribute(core, model_id, "location")), allow_write(user_id, model_id))
  205. else:
  206. output("You are not allowed to read this model!")
  207. else:
  208. output("Could not find model!")
  209. elif (cmd == "model_delete"):
  210. // Delete a model and all of its related transformations
  211. String model_id
  212. output("=================================================")
  213. output("WARNING: Deletion is a very destructive operation")
  214. output(" as it also deletes all transformations ")
  215. output(" defined which make use of this model! ")
  216. output("=================================================")
  217. output("")
  218. output("Currently not supported!")
  219. elif (cmd == "model_list"):
  220. // List all models
  221. Element models
  222. String m
  223. models = allInstances(core, "Model")
  224. while (read_nr_out(models) > 0):
  225. m = set_pop(models)
  226. output((" " + (read_attribute(core, m, "name")) + " : ") + read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name"))
  227. elif (cmd == "model_list_full")
  228. // List all models with full info
  229. Element models
  230. String m
  231. String permissions
  232. String owner
  233. String group
  234. String name
  235. String type
  236. models = allInstances(core, "Model")
  237. while (read_nr_out(models) > 0):
  238. m = set_pop(models)
  239. permissions = read_attribute(core, m, "permissions")
  240. owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
  241. group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
  242. name = read_attribute(core, m, "name")
  243. size = read_nr_out(dict_read(import_node(read_attribute(core, m, "location")), "model"))
  244. type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
  245. output(((((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + size) + " ") + name) + " : ") + type)
  246. elif (cmd == "permission_modify"):
  247. String permissions
  248. String model_id
  249. output("Which model do you want to change permissions of?")
  250. model_id = get_model_id(input())
  251. if (model_id != ""):
  252. if (get_relation_to_model(user_id, model_id) == 0):
  253. output("New permissions?")
  254. permissions = input()
  255. Boolean fail
  256. Integer i
  257. i = 0
  258. if (string_length(permissions) != 3):
  259. fail = True
  260. while (bool_and(bool_not(fail), i < 3)):
  261. permission = cast_s2i(string_read(permissions, i))
  262. if (bool_or(permission < 0, permission > 2)):
  263. fail = True
  264. if (bool_not(fail)):
  265. unset_attribute(core, model_id, "permissions")
  266. instantiate_attribute(core, model_id, "permissions", permissions)
  267. else:
  268. output("Permissions must be a string of three characters with each character being a digit between 0 and 2")
  269. else:
  270. output("Permission denied!")
  271. else:
  272. output("No such model!")
  273. elif (cmd == "permission_owner"):
  274. String permissions
  275. String model_id
  276. String user_id
  277. output("Which model do you want to change owner of?")
  278. model_id = get_model_id(input())
  279. if (model_id != ""):
  280. if (get_relation_to_model(user_id, model_id) == 0):
  281. output("New owner?")
  282. user_id = get_user_id(input())
  283. if (user_id != ""):
  284. model_delete_element(set_pop(allOutgoingAssociationInstances(core, model_id, "owner")))
  285. instantiate_link(core, "owner", "", model_id, user_id)
  286. else:
  287. output("No such user!")
  288. else:
  289. output("Permission denied!")
  290. else:
  291. output("No such model!")
  292. elif (cmd == "permission_group"):
  293. String permissions
  294. String model_id
  295. String group_id
  296. output("Which model do you want to change permissions of?")
  297. model_id = get_model_id(input())
  298. if (model_id != ""):
  299. if (get_relation_to_model(user_id, model_id) == 0):
  300. output("New group?")
  301. group_id = get_group_id(input())
  302. if (group_id != ""):
  303. model_delete_element(set_pop(allOutgoingAssociationInstances(core, model_id, "group")))
  304. instantiate_link(core, "group", "", model_id, group_id)
  305. else:
  306. output("No such group!")
  307. else:
  308. output("Permission denied!")
  309. else:
  310. output("No such model!")
  311. elif (cmd == "group_create"):
  312. // Create a new group and become its owner
  313. String group_id
  314. String name
  315. output("Which group do you want to create?")
  316. name = input()
  317. group_id = get_group_id(name)
  318. if (group_id == ""):
  319. group_id = instantiate_node(core, "Group", "")
  320. instantiate_attribute(core, group_id, "name", name)
  321. instantiate_link(core, "belongsTo", "", user_id, group_id)
  322. isntantiate_link(core, "owner", "", group_id, user_id)
  323. output("Group created!")
  324. else:
  325. output("Group already exists")
  326. elif (cmd == "group_delete"):
  327. // Delete an existing group
  328. String group_id
  329. String name
  330. output("Which group do you want to delete?")
  331. name = input()
  332. group_id = get_group_id(name)
  333. if (group_id != ""):
  334. if (allow_group_modify(user_id, group_id)):
  335. model_delete_element(core, group_id)
  336. else:
  337. output("Permission denied")
  338. else:
  339. output("No such group")
  340. elif (cmd == "group_owner_add"):
  341. // Add an owner to your group
  342. String group_id
  343. output("Which group do you want to add an owner to?")
  344. group_id = get_group_id(input())
  345. if (group_id != ""):
  346. if (allow_group_modify(user_id, group_id)):
  347. output("Which user do you want to make an owner?")
  348. other_user_id = get_user_id(input())
  349. if (other_user_id != ""):
  350. Element overlap
  351. overlap = set_overlap(allIncomingAssociationInstances(core, user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  352. if (read_nr_out(overlap) == 0):
  353. instantiate_link(core, "owner", "", group_id, user_id)
  354. overlap = set_overlap(allOutgoingAssociationInstances(core, user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  355. if (read_nr_out(overlap) == 0):
  356. instantiate_link(core, "belongsTo", "", user_id, group_id)
  357. output("New owner added to group!")
  358. else:
  359. output("User is already an owner!")
  360. else:
  361. output("No such user")
  362. else:
  363. output("Permission denied!")
  364. else:
  365. output("No such group")
  366. elif (cmd == "group_owner_delete"):
  367. // Remove an owner from your group
  368. String group_id
  369. output("Which group do you want to disown someone from?")
  370. group_id = get_group_id(input())
  371. if (group_id != ""):
  372. if (allow_group_modify(user_id, group_id)):
  373. output("Which user do you want to disown?")
  374. other_user_id = get_user_id(input())
  375. if (other_user_id != ""):
  376. Element overlap
  377. overlap = set_overlap(allOutgoingAssociationInstances(core, user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  378. if (read_nr_out(overlap) > 0):
  379. overlap = set_overlap(allIncomingAssociationInstances(core, user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  380. if (read_nr_out(overlap) > 0):
  381. model_delete_element(core, set_pop(overlap))
  382. output("Disowned group from user!")
  383. else:
  384. output("User is not even an owner of the group!")
  385. else:
  386. output("User is not even a member of the group!")
  387. else:
  388. output("No such user")
  389. else:
  390. output("Permission denied!")
  391. else:
  392. output("No such group")
  393. elif (cmd == "group_join"):
  394. // Add someone to your group
  395. String group_id
  396. output("Which group do you want to add someone to?")
  397. group_id = get_group_id(input())
  398. if (group_id != ""):
  399. if (allow_group_modify(user_id, group_id)):
  400. output("Which user do you want to add?")
  401. other_user_id = get_user_id(input())
  402. if (other_user_id != ""):
  403. Element overlap
  404. overlap = set_overlap(allOutgoingAssociationInstances(core, user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  405. if (read_nr_out(overlap) == 0):
  406. instantiate_link(core, "belongsTo", "", user_id, group_id)
  407. output("User added to the group!")
  408. else:
  409. output("User is already a member of the group!")
  410. else:
  411. output("No such user")
  412. else:
  413. output("Permission denied!")
  414. else:
  415. output("No such group")
  416. elif (cmd == "group_kick"):
  417. // Remove someone from your group
  418. String group_id
  419. output("Which group do you want to kick someone from?")
  420. group_id = get_group_id(input())
  421. if (group_id != ""):
  422. if (allow_group_modify(user_id, group_id)):
  423. output("Which user do you want to kick?")
  424. other_user_id = get_user_id(input())
  425. if (other_user_id != ""):
  426. Element overlap
  427. overlap = set_overlap(allOutgoingAssociationInstances(core, user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  428. if (read_nr_out(overlap) > 0):
  429. model_delete_element(core, set_pop(overlap))
  430. // Check if user was an owner as well
  431. overlap = set_overlap(allIncomingAssociationInstances(core, user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  432. if (read_nr_out(overlap) > 0):
  433. model_delete_element(core, set_pop(overlap))
  434. output("User kicked!")
  435. else:
  436. output("User is not even a member of the group!")
  437. else:
  438. output("No such user")
  439. else:
  440. output("Permission denied!")
  441. else:
  442. output("No such group")
  443. elif (cmd == "group_list"):
  444. // List all groups you are a member of (and whether you are admin or not!)
  445. Element groups
  446. String group_id
  447. String admin
  448. groups = allAssociationDestinations(core, user_id, "belongsTo")
  449. while (True):
  450. group_id = set_pop(groups)
  451. if (set_in(allAssociation(core, group_id, "owner"), user_id)):
  452. admin = " A "
  453. else:
  454. admin = " "
  455. output(admin + read_attribute(core, group_id, "name"))
  456. elif (cmd == "admin_promote"):
  457. // Promote a user to admin status
  458. if (is_admin(user_id)):
  459. String other_user_id
  460. output("Which user do you want to promote?")
  461. other_user_id = get_user_id(input())
  462. if (other_user_id != ""):
  463. unset_attribute(core, other_user_id, "admin")
  464. instantiate_attribute(core, other_user_id, "admin", True)
  465. output("Permissions granted!")
  466. else:
  467. output("No such user!")
  468. else:
  469. output("Permission denied!")
  470. elif (cmd == "admin_demote"):
  471. // Demote a user to normal status
  472. if (is_admin(user_id)):
  473. String other_user_id
  474. output("Which user do you want to demote?")
  475. other_user_id = get_user_id(input())
  476. if (other_user_id != ""):
  477. unset_attribute(core, other_user_id, "admin")
  478. instantiate_attribute(core, other_user_id, "admin", False)
  479. output("Permissions revoked!")
  480. else:
  481. output("No such user!")
  482. else:
  483. output("Permission denied!")
  484. elif (cmd == "exit"):
  485. // Exit by actually removing the user and decoupling it from all of its models
  486. // Restarting with the same user name will NOT grant you access to anything of the previous user with that same name
  487. do_continue = False
  488. // Delete user from Core Formalism
  489. model_delete_element(core, user_id)
  490. output("Goodbye!")
  491. return !