include "modelling.alh" include "library.alh" Element core = ? Void function main(): // Initialize the Core Formalism String core_location String admin_group String admin_user core_location = "models/CoreFormalism" // Create the Model itself and make public core = instantiate_model(import_node(core_location)) // Create admin group admin_group = instantiate_node(core, "Group", "") instantiate_attribute(core, admin_group, "name", "admin") // Create admin user admin_user = instantiate_node(core, "User", "") instantiate_attribute(core, admin_user, "name", get_username()) instantiate_attribute(core, admin_user, "admin", True) // Create link between admin user and group instantiate_link(core, "ownedBy", "", admin_group, admin_user) instantiate_link(core, "belongsTo", "", admin_user, admin_group) // Add the core formalism already core_model = instantiate_node(core, "Model", "") instantiate_attribute(core, core_model, "name", "CoreFormalism") instantiate_attribute(core, core_model, "location", core_location) instantiate_attribute(core, core_model, "permissions", "330") // Make necessary links for the formalism to the owners instantiate_link(core, "group", "", core_model, admin_group) instantiate_link(core, "owner", "", core_model, admin_user) // Switch all new users to the user_function // This accesses the bootstrap level, so do not change this unless you know what you are doing Element root root = read_root() dict_del(root["__hierarchy"], "__IP") dict_add(root["__hierarchy"], "__IP", user_function) // Call this for ourselves as well user_function_skip_init(admin_user) // Done, so finish up // Admin user will have been deleted by the user_function as usual // Note that if there are no admin users left, it will be very difficult to manage, as nobody will have admin permissions! return ! Integer function get_relation_to_model(user_id : String, model_id : String): if (set_in(allAssociationDestinations(core, model_id, "owner"), user_id)): // We are the owner return 0! else: String group_id group_id = set_pop(allAssociationDestinations(core, model_id, "group")) if (set_in(allAssociationDestinations(core, user_id, "belongsTo"), group_id)): // We are in the owning group return 1! else: // We are not related whatsoever return 2! Boolean function is_admin(user_id : String): if (read_attribute(core, user_id, "admin")): return True! else: return False! Boolean function allow_read(user_id : String, model_id : String): if (is_admin(user_id)): // Is admin, so always allow return True! else: // Check permissions String permission permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id)) if (bool_or(permission == "1", permission == "3")): return True! else: return False! Boolean function allow_write(user_id : String, model_id : String): if (is_admin(user_id)): // Is admin, so always allow return True! else: // Check permissions String permission permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id)) if (bool_or(permission == "2", permission == "3")): return True! else: return False! Boolean function allow_change_metadata(user_id : String, model_id : String): if (is_admin(user_id)): // Is admin, so always allow return True! else: if (get_relation_to_model(user_id, model_id) == "0"): // Only owner can chmod return True! else: return False! Void function user_function(): // Now the username is bound to the task ID, so there is no problem // TODO check whether username isn't registered yet // Add user to Core Formalism String user_id user_id = instantiate_node(core, "User", "") instantiate_attribute(core, user_id, "name", get_username()) instantiate_attribute(core, user_id, "admin", False) // Now call with user created user_function_skip_init(user_id) // User destroyed already, so just stop execution return ! String function get_model_id(name : String): Element models String model models = allInstances(core, "Model") while (read_nr_out(models) > 0): model = set_pop(models) if (read_attribute(core, model, "name") == name): return model! return ""! Void function user_function_skip_init(user_id : String) Boolean do_continue String cmd do_continue = True output("Welcome to the Model Management Interface v2.0!") output("Use the 'help' command for a list of possible commands") while (do_continue): output("Ready for command...") cmd = input() if (cmd == "help"): output("Model operations") output(" model_add -- Add a new model") output(" model_modify -- Modify an existing model") output(" model_delete -- [TODO] Delete a model and all related transformations") output(" model_list -- List all models") output(" model_list_full -- List all models with full info") output("") output("Transformation-specific operations") output(" transformation_add -- TODO") output(" transformation_source_add -- TODO") output(" transformation_source_delete -- TODO") output(" transformation_target_add -- TODO") output(" transformation_target_delete -- TODO") output(" transformation_execute -- TODO") output("") output("Model permission operations") output(" permission_modify -- TODO") output(" permission_owner -- TODO") output(" permission_group -- TODO") output("") output("Group operations") output(" group_create -- TODO") output(" group_delete -- TODO") output(" group_owner -- TODO") output(" group_join -- TODO") output(" group_kick -- TODO") output("") output("Admin operations") output(" admin_promote -- Promote a user to admin status") output(" admin_demote -- Demote a user to normal status") output("") output("General operations") output(" account_delete -- Remove current user and revoke all permissions ") elif (cmd == "model_add"): // Model addition operation, which uses model upload commands of the compiler String name String type String location Element new_model output("Creating new model!") output("Model type?") type_id = get_model_id(input()) if (type_id != ""): // Type exists if (allow_read(user_id, type_id)): // And is readable output("Model name?") name = input() if (get_model_id(name) == ""): // Model doesn't exist yet output("Waiting for model constructors...") // TODO update for access control new_model = construct_model(read_attribute(core, type_id, "location")) output("Model upload success!") location = "/models/" + cast_id2s(new_model) export_node(new_model, location) // Manage meta-info new_model_id = instantiate_node(core, "Model", "") instantiate_attribute(core, new_model_id, "name", name) instantiate_attribute(core, new_model_id, "location", location) instantiate_attribute(core, new_model_id, "permissions", "300") instantiate_link(core, "owner", "", new_model_id, user_id) instantiate_link(core, "instanceOf", "", new_model_id, type_id) output("Meta-info correctly set!") else: output("Model with that name already exists!") else: output("You are not allowed to read this type model!") else: output("Could not find type model!") elif (cmd == "model_modify"): // Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control String model_id output("Which model do you want to modify?") model_id = get_model_id(input()) if (model_id != ""): if (allow_read(user_id, model_id)): mini_modify(import_node(read_attribute(core, model_id, "location")), allow_write(user_id, model_id)) else: output("You are not allowed to read this model!") else: output("Could not find model!") elif (cmd == "model_delete"): // Delete a model and all of its related transformations String model_id output("=================================================") output("WARNING: Deletion is a very destructive operation") output(" as it also deletes all transformations ") output(" defined which make use of this model! ") output("=================================================") output("") output("Currently not supported!") elif (cmd == "model_list"): // List all models Element models String m models = allInstances(core, "Model") while (read_nr_out(models) > 0): m = set_pop(models) output((" " + (read_attribute(core, m, "name")) + " : ") + read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")) elif (cmd == "model_list_full") // List all models with full info Element models String m String permissions String owner String group String name String type models = allInstances(core, "Model") while (read_nr_out(models) > 0): m = set_pop(models) permissions = read_attribute(core, m, "permissions") owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name") group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name") name = read_attribute(core, m, "name") size = read_nr_out(dict_read(import_node(read_attribute(core, m, "location")), "model")) type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name") output(((((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + size) + " ") + name) + " : ") + type) elif (cmd == "admin_promote"): // Promote a user to admin status if (is_admin(user_id)): String other_user_id output("Which user do you want to promote?") other_user_id = get_user_id(input()) if (other_user_id != ""): unset_attribute(core, other_user_id, "admin") instantiate_attribute(core, other_user_id, "admin", True) output("Permissions granted!") else: output("No such user!") else: output("Permission denied!") elif (cmd == "admin_demote"): // Demote a user to normal status if (is_admin(user_id)): String other_user_id output("Which user do you want to demote?") other_user_id = get_user_id(input()) if (other_user_id != ""): unset_attribute(core, other_user_id, "admin") instantiate_attribute(core, other_user_id, "admin", False) output("Permissions revoked!") else: output("No such user!") else: output("Permission denied!") elif (cmd == "exit"): // Exit by actually removing the user and decoupling it from all of its models // Restarting with the same user name will NOT grant you access to anything of the previous user with that same name do_continue = False // Delete user from Core Formalism model_delete_element(core, user_id) output("Goodbye!") return !