def find_token(self, token_value): dbgw = dbgateway.get() item_id, json_data = dbgw.find_token(token_value) if not item_id is None: return item_id, json.loads(json_data) else: return None, None
def get_class_from_type_id(type_id): dbgw = dbgateway.get() _, name, json_data, _, _, _ = dbgw.load(type_id) item_data = json.loads(json_data) props = item_data["props"] class_name = props["item_class"] return get_class(class_name), name
def create_token(self, item_id, length, data, **kwargs): token_value = generate_token_value(length) expires_at = in_future(**kwargs).isoformat() dbgw = dbgateway.get() json_data = json.dumps(data) dbgw.create_token(item_id, token_value, json_data, expires_at) return token_value, expires_at
def get_account(self, item_id): global account_item_handle if account_item_handle is None: account_item_handle = self.find("/system/types/account") dbgw = dbgateway.get() account_id = dbgw.get_first_parent_of_type(item_id, account_item_handle.item_id) account_path = self.get_path(account_id) return ItemHandle(path=account_path, item_id=account_id)
def create_file_version(self, item_id, previous_version, user_handle): dbgw = dbgateway.get() if previous_version and dbgw.get_file_version(item_id, previous_version)[0] is None: raise ServiceException(409, "Unknown previous version: {0}".format(previous_version)) file_version = dbgw.create_file_version(item_id, previous_version, user_handle.item_id) if previous_version is not None: dbgw.copy_file_blocks(item_id, file_version, previous_version) return file_version
def save(self, item, user_handle): item_data = { "props": item.props, "saved_by_path": user_handle.path, "created_by_path": item.created_by_path } json_data = json.dumps(item_data) dbgw = dbgateway.get() dbgw.save_item_version(item.handle.item_id) return dbgw.update_item(item.handle.item_id, json_data, user_handle.item_id)
def finalize_version(self, item_id, file_version, last_block_number): dbgw = dbgateway.get() if last_block_number is not None: dbgw.delete_trailing_file_blocks(item_id, file_version, last_block_number) file_length = 0 blocks = dbgw.list_file_blocks(item_id, file_version) block_hashes = [] for _, _, block_length, block_hash, _ in blocks: file_length += block_length block_hashes.append(block_hash) file_hash = _get_blocks_hash(block_hashes) dbgw.set_file_version_length_hash(item_id, file_version, file_length, file_hash) return file_length, file_hash
def list_versions(self, item_id): dbgw = dbgateway.get() result = [] for file_version, previous_version, length, hash, created_at, created_by in dbgw.list_file_versions(item_id): result.append({ "file_version": file_version, "previous_version": previous_version, "file_length": length, "file_hash": hash, "created_at": created_at.isoformat(), "created_by": created_by }) return result
def list_blocks(self, item_id, file_version): dbgw = dbgateway.get() result = [] for block_number, data_file_version, block_length, block_hash, created_at in \ dbgw.list_file_blocks(item_id, file_version): result.append({ "block_number": block_number, "data_file_version": data_file_version if data_file_version is not None else file_version, "block_length": block_length, "block_hash": block_hash, "created_at": created_at.isoformat() }) return result
def write_file_block(self, item_id, file_version, block_number, block_data, last_block): if not last_block and len(block_data) < BLOCK_LENGTH: raise ServiceException(403, "Block length less than {}".format(BLOCK_LENGTH)) dbgw = dbgateway.get() if self._is_file_version_completed(dbgw, item_id, file_version): raise ServiceException(403, "File version is complete") block_hash = _get_data_hash(block_data) if dbgw.get_file_block_hash(item_id, file_version, block_number): # Already a block at this location, so update existing block to overwrite existing data dbgw.update_file_block(item_id, file_version, block_number, block_hash, block_data) else: # Create a new block dbgw.create_file_block(item_id, file_version, block_number, block_hash, block_data) return block_hash
def load_template_json(self, type_name, template_name="template"): dbgw = dbgateway.get() type_id, _, _ = dbgw.find_id(self._find_system_types_folder_id(dbgw), type_name) template_id, _, _ = dbgw.find_id(type_id, template_name) if template_id is not None: return dbgw.load(template_id)[2] # Type doesn't have its own template so use the item type template type_id, _, _ = dbgw.find_id(self._find_system_types_folder_id(dbgw), "item") template_id, _, _ = dbgw.find_id(type_id, template_name) if template_id is not None: return dbgw.load(template_id)[2] # Oops - no templates available return "{}"
def load_init_data(path): init_data = load_json_with_comments(path) dbgw = dbgateway.get() types_to_resolve = [] type_names_to_class_names = {} for data in init_data: item_path = data["path"] item_props = data["props"] if "props" in data else {} item_auth = data["auth"] if "auth" in data else {} item_type = data["type"] item_title = data["title"] if "title" in data else {} item_name = os.path.basename(item_path) if item_path == "/": parent_id = None item_name = "" parent_id_path = "" else: parent_path = os.path.dirname(item_path) parent_id, parent_id_path = find_item_id(dbgw, parent_path) search_text = item_name if item_title: search_text += " " + item_title item_data = { "auth": item_auth, "props": item_props, "saved_by_path": "/users/system", "created_by_path": "/users/system", "title": item_title } dbgw.create_item_initial(parent_id, item_name, parent_id_path, json.dumps(item_data), search_text) types_to_resolve.append((item_path, item_type)) if item_type == "type": class_name = item_props["item_class"] type_names_to_class_names[item_name] = class_name type_type_id, _ = find_item_id(dbgw, "/system/types/type") system_user_id, _ = find_item_id(dbgw, "/users/system") for item_path, item_type in types_to_resolve: type_path = "/system/types/" + item_type type_id, _ = find_item_id(dbgw, type_path) item_id, _ = find_item_id(dbgw, item_path) if item_type in type_names_to_class_names: item_class = type_names_to_class_names[item_type] else: item_data = json.loads(dbgw.load(type_id)[2]) item_class = item_data["props"]["item_class"] type_id_path = find_type_path(dbgw, item_class) dbgw.set_item_type_user(item_id, type_id, type_id_path, system_user_id)
def load_init_data(path): init_data = load_json_with_comments(path) dbgw = dbgateway.get() types_to_resolve = [] type_names_to_class_names = {} for data in init_data: item_path = data["path"] item_props = data["props"] if "props" in data else {} item_auth = data["auth"] if "auth" in data else {} item_type = data["type"] item_title = data["title"] if "title" in data else {} item_name = os.path.basename(item_path) if item_path == "/": parent_id = None item_name = "" parent_id_path = "" else: parent_path = os.path.dirname(item_path) parent_id, parent_id_path = find_item_id(dbgw, parent_path) search_text = item_name if item_title: search_text += " " + item_title item_data = { "auth": item_auth, "props": item_props, "saved_by_path": "/users/system", "created_by_path": "/users/system", "title": item_title } dbgw.create_item_initial(parent_id, item_name, parent_id_path, json.dumps(item_data), search_text) types_to_resolve.append((item_path, item_type)) if item_type == "type": class_name = item_props["item_class"] type_names_to_class_names[item_name] = class_name type_type_id, _ = find_item_id(dbgw, "/system/types/type") system_user_id, _ = find_item_id(dbgw, "/users/system") for item_path,item_type in types_to_resolve: type_path = "/system/types/" + item_type type_id, _ = find_item_id(dbgw, type_path) item_id, _ = find_item_id(dbgw, item_path) if item_type in type_names_to_class_names: item_class = type_names_to_class_names[item_type] else: item_data = json.loads(dbgw.load(type_id)[2]) item_class = item_data["props"]["item_class"] type_id_path = find_type_path(dbgw, item_class) dbgw.set_item_type_user(item_id, type_id, type_id_path, system_user_id)
def list_children(self, item_id, return_dict): result = {} if return_dict else [] dbgw = dbgateway.get() for item_id, name, type_id, public_data in dbgw.list_child_items(item_id): entry = { "server_id": "#" + str(item_id), "type": self.get_type_name(type_id) } props = None cls, _ = get_class_from_type_id(type_id) if hasattr(cls, "list_property_selector"): list_property_selector = getattr(cls, "list_property_selector") props = list_property_selector(json.loads(public_data)) entry["props"] = props if return_dict: result[name] = entry else: entry["name"] = name result.append(entry) return result
def find(self, path, user_handle=None): start = perf.start() dbgw = dbgateway.get() path_parts = path.split("/")[1:] current_id = 1 user_auth_level = authorize_root(user_handle) id_path = str(current_id) version = -1 if path != "/": if len(path_parts) == 0: current_id = None id_path = None user_auth_level = AuthLevels["none"] else: for part in path_parts: # Find the next child current_id, item_auth, version = dbgw.find_id( current_id, part, True) if current_id is None: # Can't find a child item with that name user_auth_level = AuthLevels["none"] break elif user_handle and current_id == user_handle.item_id: # users can always edit themselves user_auth_level = AuthLevels["editor"] elif item_auth: # We have found a child item, and it specifies authorization values user_auth_level = self.authorize( item_auth, user_handle) id_path += "." + str(current_id) else: current_id = 1 if user_handle and user_handle.path == "/users/system": user_auth_level = AuthLevels["system"] else: user_auth_level = AuthLevels["reader"] # Always return a new ItemHandle, even if we can't find anything or we have no access result = ItemHandle(path, current_id, version, id_path, user_auth_level, user_handle) perf.end(__name__, start) return result
def load_type(self, type_name): dbgw = dbgateway.get() if ItemLoader.item_type_id is None: ItemLoader.item_type_id, _, _ = dbgw.find_id( self._find_system_types_folder_id(dbgw), "item") type_id, _, _ = dbgw.find_id(self._find_system_types_folder_id(dbgw), type_name) if type_id is None: return None _, _, json_data, _, _, _ = dbgw.load(type_id) type_item = TypeItem() type_item.handle = ItemHandle("/system/types/" + type_name, type_id, 0, None, get_authorization_level("reader"), None) if not type_item.handle.can_read(): return None item_data = json.loads(json_data) for name, value in item_data.items(): setattr(type_item, name, value) setattr(type_item, "type_path", self.find_type_path(type_item)) return type_item
def load(self, handle): start = perf.start() if not handle.item_id: return None dbgw = dbgateway.get() type_id, name, json_data, created_at, saved_at, deletable = dbgw.load( handle.item_id) cls, type_name = get_class_from_type_id(type_id) item = cls() item.handle = handle item.name = name item.type_name = type_name item.created_at = created_at item.saved_at = saved_at item.deletable = deletable item_data = json.loads(json_data) item.props = item_data["props"] item.created_by_path = item_data["created_by_path"] item.saved_by_path = item_data["saved_by_path"] perf.end(__name__, start) return item
def list_children(self, item_id, return_dict): result = {} if return_dict else [] dbgw = dbgateway.get() for item_id, name, type_id, public_data in dbgw.list_child_items( item_id): entry = { "server_id": "#" + str(item_id), "type": self.get_type_name(type_id) } props = None cls, _ = get_class_from_type_id(type_id) if hasattr(cls, "list_property_selector"): list_property_selector = getattr(cls, "list_property_selector") props = list_property_selector(json.loads(public_data)) entry["props"] = props if return_dict: result[name] = entry else: entry["name"] = name result.append(entry) return result
def find(self, path, user_handle=None): start = perf.start() dbgw = dbgateway.get() path_parts = path.split("/")[1:] current_id = 1 user_auth_level = authorize_root(user_handle) id_path = str(current_id) version = -1 if path != "/": if len(path_parts) == 0: current_id = None id_path = None user_auth_level = AuthLevels["none"] else: for part in path_parts: # Find the next child current_id, item_auth, version = dbgw.find_id(current_id, part, True) if current_id is None: # Can't find a child item with that name user_auth_level = AuthLevels["none"] break elif user_handle and current_id == user_handle.item_id: # users can always edit themselves user_auth_level = AuthLevels["editor"] elif item_auth: # We have found a child item, and it specifies authorization values user_auth_level = self.authorize(item_auth, user_handle) id_path += "." + str(current_id) else: current_id = 1 if user_handle and user_handle.path == "/users/system": user_auth_level = AuthLevels["system"] else: user_auth_level = AuthLevels["reader"] # Always return a new ItemHandle, even if we can't find anything or we have no access result = ItemHandle(path, current_id, version, id_path, user_auth_level, user_handle) perf.end(__name__, start) return result
def set_item_name(self, item_handle, name): dbgw = dbgateway.get() dbgw.set_item_name(item_handle.item_id, name)
def create(self, parent_item, name, type_item, json_data, user_handle): dbgw = dbgateway.get() return dbgw.create_item(parent_item.handle.item_id, name, parent_item.handle.id_path, type_item.handle.item_id, type_item.type_path, json_data, user_handle.item_id, "")
def get_block_data(self, item_id, file_version, block_number): dbgw = dbgateway.get() data_file_version = dbgw.get_file_block_data_file_version(item_id, file_version, block_number) if data_file_version is not None: file_version = data_file_version return dbgw.get_file_block_data(item_id, file_version, block_number)
def get_version_length(self, item_id, file_version): dbgw = dbgateway.get() length, file_hash, _ = dbgw.get_file_version(item_id, file_version) return length if file_hash else None
def get_type_name(self, type_id): dbgw = dbgateway.get() return dbgw.get_item_name(type_id)
def create_initial_file_version(self, item_id, user_handle): dbgw = dbgateway.get() dbgw.create_file_version(item_id, None, user_handle.item_id)
def requires_init_data(self): dbgw = dbgateway.get() return dbgw.count_items() == 0
def set_private(self, item_handle, data, user_handle): dbgw = dbgateway.get() return dbgw.update_private(item_handle.item_id, json.dumps(data), user_handle.item_id)
def delete_item(self, item_id): dbgw = dbgateway.get() dbgw.delete_item(item_id)
def get_path(self, item_id): dbgw = dbgateway.get() id_path = dbgw.get_item_id_path(item_id) path = "/".join( [dbgw.get_item_name(int(id)) for id in id_path.split(".")]) return path if len(path) > 0 else "/"
def get_private(self, item_id): dbgw = dbgateway.get() private_data = dbgw.get_private(item_id) return json.loads(private_data) if private_data is not None else {}
import unittest import dbgateway import init_loader from processor import Processor from worker import ServiceException dbgateway.locator = "pq://*****:*****@localhost/perspective" dbgw = dbgateway.get() class ProcessorTests(unittest.TestCase): @classmethod def setUpClass(cls): dbgw.reset() init_loader.load_init_data("../database/init.json") @classmethod def tearDownClass(self): dbgw.reset() def test_load_root_account(self): processor = Processor() processor.execute("/", "get", "/", {}) def test_create_user_login(self): processor = Processor() # Create a user processor.execute("/", "post", "/users/system", {"new_name": "test_user", "new_password": "******"}) # Login as user response = processor.check_login("/", "post", {"name": "test_user", "password": "******"})
import unittest import dbgateway from file_manager import FileManager from item_finder import ItemFinder import init_loader from worker import ServiceException dbgateway.locator = "pq://*****:*****@localhost/perspective" dbgw = dbgateway.get() class FileManagerTests(unittest.TestCase): def setUp(self): dbgw.reset() init_loader.load_init_data("../database/init.json") def tearDown(self): dbgw.reset() def test_create_file_versions(self): file_manager = FileManager() finder = ItemFinder() handle = finder.find("/") user_handle = finder.find("/users/system") file_version = file_manager.create_file_version( handle.item_id, None, user_handle) self.assertEquals(file_version, 0) file_version = file_manager.create_file_version( handle.item_id, None, user_handle) self.assertEquals(file_version, 1) file_version = file_manager.create_file_version(
def get_path(self, item_id): dbgw = dbgateway.get() id_path = dbgw.get_item_id_path(item_id) path = "/".join([dbgw.get_item_name(int(id)) for id in id_path.split(".")]) return path if len(path) > 0 else "/"