diff --git a/seahub/utils/ccnet_db.py b/seahub/utils/ccnet_db.py index 4cdce9265a..158fb3fd32 100644 --- a/seahub/utils/ccnet_db.py +++ b/seahub/utils/ccnet_db.py @@ -28,12 +28,14 @@ class CcnetUsers(object): self.role = kwargs.get('role') self.passwd = kwargs.get('passwd') + class CcnetUserRole(object): - + def __init__(self, **kwargs): self.role = kwargs.get('role') self.is_manual_set = kwargs.get('is_manual_set') + class CcnetDB: def __init__(self): @@ -50,11 +52,11 @@ class CcnetDB: `{self.db_name}`.`Group` g ON o.group_id=g.group_id WHERE - org_id={org_id} AND parent_group_id<>0; + org_id=%s AND parent_group_id<>0; """ groups = [] with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [org_id]) for item in cursor.fetchall(): group_id = item[0] group_name = item[1] @@ -75,60 +77,52 @@ class CcnetDB: def list_eligible_users(self, start, limit, is_active=None, role=None, q=None): - def status(is_active): - return f'AND t1.is_active={is_active} ' + conditions = [] + params = [] - def is_role(role): - if role == 'default': - return 'AND (t2.role is null or t2.role = "default") ' - else: - return f'AND t2.role = "{role}" ' + if is_active is not None: + conditions.append("t1.is_active = %s") + params.append(is_active) - def search(q): - return f'AND t1.email LIKE "%{q}%" ' - - search_clause = '' - if is_active: - search_clause += status(is_active) if role: - search_clause += is_role(role) + if role == 'default': + conditions.append("(t2.role IS NULL OR t2.role = 'default')") + else: + conditions.append("t2.role = %s") + params.append(role) + if q: - search_clause += search(q) + conditions.append("t1.email LIKE %s") + params.append(f"%{q}%") + + base_condition = "t1.email NOT LIKE '%%@seafile_group'" + where_clause = f"WHERE {base_condition}" + if conditions: + where_clause += " AND " + " AND ".join(conditions) count_sql = f""" - SELECT count(1) - FROM - `{self.db_name}`.`EmailUser` t1 - LEFT JOIN - `{self.db_name}`.`UserRole` t2 - ON - t1.email = t2.email - WHERE - t1.email NOT LIKE '%%@seafile_group' %s - ORDER BY t1.id - """ % search_clause + SELECT COUNT(1) + FROM `{self.db_name}`.`EmailUser` t1 + LEFT JOIN `{self.db_name}`.`UserRole` t2 ON t1.email = t2.email + {where_clause} + ORDER BY t1.id + """ sql = f""" - SELECT t1.id, t1.email, t1.is_staff, t1.is_active, t1.ctime, t2.role, t1.passwd - FROM - `{self.db_name}`.`EmailUser` t1 - LEFT JOIN - `{self.db_name}`.`UserRole` t2 - ON - t1.email = t2.email - WHERE - t1.email NOT LIKE '%%@seafile_group' %s - ORDER BY t1.id - LIMIT {limit} OFFSET {start}; - """ % search_clause + SELECT t1.id, t1.email, t1.is_staff, t1.is_active, t1.ctime, t2.role, t1.passwd + FROM `{self.db_name}`.`EmailUser` t1 + LEFT JOIN `{self.db_name}`.`UserRole` t2 ON t1.email = t2.email + {where_clause} + ORDER BY t1.id + LIMIT %s OFFSET %s; + """ users = [] with connection.cursor() as cursor: - cursor.execute(count_sql) - cursor.execute(count_sql) + cursor.execute(count_sql, params) total_count = int(cursor.fetchone()[0]) - cursor.execute(sql) + cursor.execute(sql, params + [limit, start]) for item in cursor.fetchall(): user_id = item[0] email = item[1] @@ -159,10 +153,10 @@ class CcnetDB: FROM `{self.db_name}`.`GroupUser` WHERE - group_id IN ({group_ids_str}) AND is_staff = 1 + group_id IN (%s) AND is_staff = 1 """ with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [group_ids_str]) result = cursor.fetchall() for user, group_id in result: if group_id in group_admins: @@ -178,16 +172,16 @@ class CcnetDB: g.creator_name = 'system admin', g.parent_group_id = -1 WHERE - g.group_id = {group_id} + g.group_id = %s """ structure_sql = f""" INSERT INTO `{self.db_name}`.`GroupStructure` (group_id, path) - VALUES ('{group_id}', '{group_id}') + VALUES (%s, %s) """ with connection.cursor() as cursor: - cursor.execute(sql) - cursor.execute(structure_sql) + cursor.execute(sql, [group_id]) + cursor.execute(structure_sql, [group_id, group_id]) def get_active_users_by_user_list(self, user_list): if not user_list: @@ -198,10 +192,12 @@ class CcnetDB: SELECT `email` FROM `{self.db_name}`.`EmailUser` WHERE - email IN ({user_list_str}) AND is_active = 1 AND email NOT LIKE '%%@seafile_group' + email IN (%s) + AND is_active = 1 + AND email NOT LIKE '%%@seafile_group' """ with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [user_list_str]) for user in cursor.fetchall(): active_users.append(user[0]) @@ -209,21 +205,25 @@ class CcnetDB: def get_org_user_count(self, org_id): sql = f""" - SELECT COUNT(1) FROM `{self.db_name}`.`OrgUser` WHERE org_id={org_id} + SELECT COUNT(1) + FROM `{self.db_name}`.`OrgUser` + WHERE org_id=%s """ user_count = 0 with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [org_id]) user_count = cursor.fetchone()[0] return user_count - + def get_user_role_from_db(self, email): sql = f""" - SELECT `role`, `is_manual_set` FROM `{self.db_name}`.`UserRole` WHERE email = '{email}'; + SELECT `role`, `is_manual_set` + FROM `{self.db_name}`.`UserRole` + WHERE email = %s; """ with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [email]) row = cursor.fetchone() if not row: role = None diff --git a/seahub/utils/db_api.py b/seahub/utils/db_api.py index a53ab9aaa6..e59d318c38 100644 --- a/seahub/utils/db_api.py +++ b/seahub/utils/db_api.py @@ -13,7 +13,9 @@ class RepoTrash(object): self.size = kwargs.get('size') self.del_time = kwargs.get('del_time') + class WikiInfo(object): + def __init__(self, **kwargs): self.repo_id = kwargs.get('repo_id') self.wiki_name = kwargs.get('wiki_name') @@ -25,7 +27,6 @@ class WikiInfo(object): self.last_modified = kwargs.get('last_modified') - class SeafileDB: def __init__(self): @@ -67,7 +68,7 @@ class SeafileDB: FROM `{self.db_name}`.`SharedRepo` s WHERE - repo_id = '{repo_id}'; + repo_id = %s; """ else: sql = f""" @@ -76,13 +77,13 @@ class SeafileDB: FROM `{self.db_name}`.`OrgSharedRepo` s WHERE - repo_id = '{repo_id}'; + repo_id = %s; """ share_info_list = [] with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [repo_id]) for item in cursor.fetchall(): info = {} @@ -108,7 +109,7 @@ class SeafileDB: FROM `{self.db_name}`.`RepoGroup` s WHERE - repo_id = '{repo_id}'; + repo_id = %s; """ else: sql = f""" @@ -117,13 +118,13 @@ class SeafileDB: FROM `{self.db_name}`.`OrgGroupRepo` s WHERE - repo_id = '{repo_id}'; + repo_id = %s; """ share_info_list = [] with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [repo_id]) for item in cursor.fetchall(): info = {} @@ -150,7 +151,7 @@ class SeafileDB: ON s.repo_id=v.repo_id WHERE - v.origin_repo = '{repo_id}'; + v.origin_repo = %s; """ else: sql = f""" @@ -161,13 +162,13 @@ class SeafileDB: ON s.repo_id=v.repo_id WHERE - v.origin_repo = '{repo_id}'; + v.origin_repo = %s; """ share_info_list = [] with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [repo_id]) for item in cursor.fetchall(): info = {} @@ -195,7 +196,7 @@ class SeafileDB: ON r.repo_id=v.repo_id WHERE - v.origin_repo = '{repo_id}'; + v.origin_repo = %s; """ else: sql = f""" @@ -206,13 +207,13 @@ class SeafileDB: ON r.repo_id=v.repo_id WHERE - v.origin_repo = '{repo_id}'; + v.origin_repo = %s; """ share_info_list = [] with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [repo_id]) for item in cursor.fetchall(): info = {} @@ -260,12 +261,17 @@ class SeafileDB: u.repo_id = o.repo_id ORDER BY e.error_time DESC - LIMIT {limit} OFFSET {start} + LIMIT %s OFFSET %s """ device_errors = [] with connection.cursor() as cursor: - cursor.execute(sql) + + if start == -1 and limit == -1: + cursor.execute(sql) + else: + cursor.execute(sql, [limit, start]) + for item in cursor.fetchall(): info = {} info['repo_id'] = item[0] @@ -287,13 +293,13 @@ class SeafileDB: sql = f""" SELECT repo_id, repo_name, head_id, owner_id, `size`, del_time FROM `{self.db_name}`.`RepoTrash` - WHERE org_id = {org_id} + WHERE org_id = %s ORDER BY del_time DESC - LIMIT {limit} OFFSET {start} + LIMIT %s OFFSET %s """ trash_repo_list = [] with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [org_id, limit, start]) for item in cursor.fetchall(): repo_id = item[0] repo_name = item[1] @@ -319,29 +325,30 @@ class SeafileDB: empty org repo trash """ def del_repo_trash(cursor, repo_ids): - del_file_count_sql = """ - DELETE FROM - `%s`.`RepoFileCount` - WHERE - repo_id in %%s; - """ % self.db_name - cursor.execute(del_file_count_sql, (repo_ids, )) - del_repo_info_sql = """ + del_file_count_sql = f""" DELETE FROM - `%s`.`RepoInfo` + `{self.db_name}`.`RepoFileCount` WHERE - repo_id in %%s; - """ % self.db_name - cursor.execute(del_repo_info_sql, (repo_ids, )) + repo_id in %s; + """ + cursor.execute(del_file_count_sql, [repo_ids]) - del_trash_sql = """ + del_repo_info_sql = f""" DELETE FROM - `%s`.`RepoTrash` + `{self.db_name}`.`RepoInfo` WHERE - repo_id in %%s; - """ % self.db_name - cursor.execute(del_trash_sql, (repo_ids,)) + repo_id in %s; + """ + cursor.execute(del_repo_info_sql, [repo_ids]) + + del_trash_sql = f""" + DELETE FROM + `{self.db_name}`.`RepoTrash` + WHERE + repo_id in %s; + """ + cursor.execute(del_trash_sql, [repo_ids]) sql_list_repo_id = f""" SELECT @@ -349,10 +356,10 @@ class SeafileDB: FROM `{self.db_name}`.`RepoTrash` t WHERE - org_id={org_id}; + org_id = %s; """ with connection.cursor() as cursor: - cursor.execute(sql_list_repo_id) + cursor.execute(sql_list_repo_id, [org_id]) repo_ids = [] for item in cursor.fetchall(): repo_id = item[0] @@ -361,81 +368,123 @@ class SeafileDB: cursor.close() def add_repos_to_org_user(self, org_id, username, repo_ids): - for repo_id in repo_ids: - sql = f""" + + sql = f""" INSERT INTO `{self.db_name}`.`OrgRepo` (org_id, repo_id, user) - VALUES ({org_id}, "{repo_id}", "{username}"); - """ - with connection.cursor() as cursor: - cursor.execute(sql) + VALUES (%s, %s, %s); + """ + with connection.cursor() as cursor: + for repo_id in repo_ids: + cursor.execute(sql, [org_id, repo_id, username]) def set_repo_type(self, repo_id, repo_type): - sql = f""" - UPDATE `{self.db_name}`. `RepoInfo` - SET `type`= '%s' - WHERE `repo_id`='%s' - """ % (repo_type, repo_id) + sql = f""" + UPDATE `{self.db_name}`.`RepoInfo` + SET `type` = %s + WHERE `repo_id` = %s; + """ with connection.cursor() as cursor: - cursor.execute(sql) + cursor.execute(sql, [repo_type, repo_id]) def get_repo_ids_in_repo(self, repo_id): + repo_ids_sql = f""" - SELECT repo_id from `{self.db_name}`.`VirtualRepo` where origin_repo="{repo_id}" - """ + SELECT repo_id + FROM `{self.db_name}`.`VirtualRepo` + WHERE origin_repo = %s; + """ + repo_ids = [repo_id, ] with connection.cursor() as cursor: try: - cursor.execute(repo_ids_sql) + cursor.execute(repo_ids_sql, [repo_id]) for item in cursor.fetchall(): repo_id = item[0] repo_ids.append(repo_id) - except: + except Exception: return repo_ids return repo_ids def set_repo_owner(self, repo_id, new_owner, org_id=None): + # transfert repo to user - repo_ids = self.get_repo_ids_in_repo(repo_id) - repo_ids_str = ','.join(["'%s'" % str(rid) for rid in repo_ids]) + if org_id: sql = f""" - UPDATE `{self.db_name}`.`OrgRepo` SET user="{new_owner}" WHERE org_id ={org_id} AND repo_id IN ({repo_ids_str}) + UPDATE `{self.db_name}`.`OrgRepo` + SET user= %s + WHERE org_id =%s AND repo_id IN (%s) """ else: sql = f""" - UPDATE `{self.db_name}`.`RepoOwner` SET owner_id="{new_owner}" WHERE repo_id IN ({repo_ids_str}) + UPDATE `{self.db_name}`.`RepoOwner` + SET owner_id= %s + WHERE repo_id IN (%s) """ + + repo_ids = self.get_repo_ids_in_repo(repo_id) + repo_ids_str = ','.join(["'%s'" % str(rid) for rid in repo_ids]) + with connection.cursor() as cursor: - cursor.execute(sql) + if org_id: + cursor.execute(sql, [new_owner, org_id, repo_ids_str]) + else: + cursor.execute(sql, [new_owner, repo_ids_str]) def set_repo_group_owner(self, repo_id, group_id, current_group_id=None, org_id=None): + # transfer repo to department + group_username = "%s@seafile_group" % group_id + current_group_username = None if current_group_id: current_group_username = "%s@seafile_group" % current_group_id + if org_id: - sql1 = f""" - DELETE From `{self.db_name}`.`OrgGroupRepo` where owner="{current_group_username}" AND repo_id="{repo_id}" AND org_id="{org_id}" AND group_id="{current_group_id}" + delete_sql = f""" + DELETE From `{self.db_name}`.`OrgGroupRepo` + WHERE owner=%s + AND repo_id=%s + AND org_id=%s + AND group_id=%s """ + sql = f""" - INSERT INTO `{self.db_name}`.`OrgGroupRepo` (org_id, repo_id, group_id, owner, permission) VALUES ({org_id}, "{repo_id}", {group_id}, "{group_username}", "rw") - ON DUPLICATE KEY UPDATE owner="{group_username}" + INSERT INTO `{self.db_name}`.`OrgGroupRepo` (org_id, repo_id, group_id, owner, permission) + VALUES (%s, %s, %s, %s, "rw") + ON DUPLICATE KEY UPDATE owner=%s """ else: - sql1 = f""" - DELETE From `{self.db_name}`.`RepoGroup` where user_name="{current_group_username}" AND repo_id="{repo_id}" AND group_id="{current_group_id}" - """ + delete_sql = f""" + DELETE FROM `{self.db_name}`.`RepoGroup` + WHERE user_name=%s + AND repo_id=%s + AND group_id=%s + """ + sql = f""" - INSERT INTO `{self.db_name}`.`RepoGroup` (repo_id, group_id, user_name, permission) VALUES ("{repo_id}", {group_id}, "{group_username}", "rw") - ON DUPLICATE KEY UPDATE user_name="{group_username}" + INSERT INTO `{self.db_name}`.`RepoGroup` (repo_id, group_id, user_name, permission) + VALUES (%s, %s, %s, "rw") + ON DUPLICATE KEY UPDATE user_name=%s """ with connection.cursor() as cursor: - if current_group_id: - cursor.execute(sql1) - cursor.execute(sql) + + if org_id: + if current_group_id: + cursor.execute(delete_sql, [current_group_username, + repo_id, org_id, current_group_id]) + cursor.execute(sql, [org_id, repo_id, group_id, + group_username, group_username]) + else: + if current_group_id: + cursor.execute(delete_sql, [current_group_username, + repo_id, current_group_id]) + cursor.execute(sql, [repo_id, group_id, + group_username, group_username]) + self.set_repo_owner(repo_id, group_username, org_id) def update_repo_user_shares(self, repo_id, new_owner, org_id=None): @@ -443,38 +492,54 @@ class SeafileDB: repo_ids_str = ','.join(["'%s'" % str(rid) for rid in repo_ids]) if org_id: sql = f""" - UPDATE `{self.db_name}`.`OrgSharedRepo` SET from_email="{new_owner}" WHERE org_id={org_id} AND repo_id IN ({repo_ids_str}) + UPDATE `{self.db_name}`.`OrgSharedRepo` + SET from_email=%s + WHERE org_id=%s + AND repo_id IN (%s) """ else: sql = f""" - UPDATE `{self.db_name}`.`SharedRepo` SET from_email="{new_owner}" WHERE repo_id IN ({repo_ids_str}) + UPDATE `{self.db_name}`.`SharedRepo` + SET from_email=%s + WHERE repo_id IN (%s) """ with connection.cursor() as cursor: - cursor.execute(sql) - + if org_id: + cursor.execute(sql, [new_owner, org_id, repo_ids_str]) + else: + cursor.execute(sql, [new_owner, repo_ids_str]) def update_repo_group_shares(self, repo_id, new_owner, org_id=None): repo_ids = self.get_repo_ids_in_repo(repo_id) repo_ids_str = ','.join(["'%s'" % str(rid) for rid in repo_ids]) if org_id: sql = f""" - UPDATE `{self.db_name}`.`OrgGroupRepo` SET owner="{new_owner}" WHERE org_id={org_id} AND repo_id IN ({repo_ids_str}) + UPDATE `{self.db_name}`.`OrgGroupRepo` + SET owner=%s + WHERE org_id=%s + AND repo_id IN (%s) """ else: sql = f""" - UPDATE `{self.db_name}`.`RepoGroup` SET user_name="{new_owner}" WHERE repo_id IN ({repo_ids_str}) + UPDATE `{self.db_name}`.`RepoGroup` + SET user_name=%s + WHERE repo_id IN (%s) """ with connection.cursor() as cursor: - cursor.execute(sql) - + if org_id: + cursor.execute(sql, [new_owner, org_id, repo_ids_str]) + else: + cursor.execute(sql, [new_owner, repo_ids_str]) def delete_repo_user_token(self, repo_id, owner): sql = f""" - DELETE FROM `{self.db_name}`.`RepoUserToken` where repo_id="{repo_id}" AND email="{owner}" + DELETE FROM `{self.db_name}`.`RepoUserToken` + WHERE repo_id=%s + AND email=%s """ with connection.cursor() as cursor: - cursor.execute(sql) - + cursor.execute(sql, [repo_id, owner]) + def get_all_wikis(self, start, limit, order_by): order_by_size_sql = f""" SELECT r.repo_id, i.name, o.owner_id, i.is_encrypted, s.size, i.status, c.file_count, i.update_time @@ -488,7 +553,7 @@ class SeafileDB: i.type = 'wiki' ORDER BY s.size DESC - LIMIT {limit} OFFSET {start} + LIMIT %s OFFSET %s """ order_by_filecount_sql = f""" SELECT r.repo_id, i.name, o.owner_id, i.is_encrypted, s.size, i.status, c.file_count, i.update_time @@ -502,7 +567,7 @@ class SeafileDB: i.type = 'wiki' ORDER BY c.file_count DESC - LIMIT {limit} OFFSET {start} + LIMIT %s OFFSET %s """ sql = f""" SELECT r.repo_id, i.name, o.owner_id, i.is_encrypted, s.size, i.status, c.file_count, i.update_time @@ -514,18 +579,21 @@ class SeafileDB: LEFT JOIN `{self.db_name}`.`RepoFileCount` c ON r.repo_id = c.repo_id WHERE i.type = 'wiki' - LIMIT {limit} OFFSET {start} + LIMIT %s OFFSET %s """ - + with connection.cursor() as cursor: + wikis = [] + if order_by == 'size': - cursor.execute(order_by_size_sql) - + cursor.execute(order_by_size_sql, [limit, start]) + elif order_by == 'file_count': - cursor.execute(order_by_filecount_sql) + cursor.execute(order_by_filecount_sql, [limit, start]) else: - cursor.execute(sql) + cursor.execute(sql, [limit, start]) + for item in cursor.fetchall(): repo_id = item[0] wiki_name = item[1]