core_algorithm.alc 19 KB

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