From 047ccae72d03fa16b7832919e892de5bf4919c86 Mon Sep 17 00:00:00 2001 From: zhengxie Date: Thu, 22 Nov 2012 14:26:39 +0800 Subject: [PATCH] Remove users' repo decrypt passwords from server when log out --- base/accounts.py | 37 ++++++++++++++++++++++++++++-- thirdpart/auth/__init__.py | 5 ++++ thirdpart/seaserv/__init__.py | 2 +- thirdpart/seaserv/service.py | 28 +++++++++++++++++------ utils.py | 43 +++++++++++++++++++++-------------- 5 files changed, 88 insertions(+), 27 deletions(-) diff --git a/base/accounts.py b/base/accounts.py index 50a5837d92..a8a7fa1470 100644 --- a/base/accounts.py +++ b/base/accounts.py @@ -11,7 +11,9 @@ from auth.models import get_hexdigest, check_password from auth import authenticate, login from registration import signals #from registration.forms import RegistrationForm -from seaserv import ccnet_threaded_rpc +from seaserv import ccnet_threaded_rpc, unset_repo_passwd, is_passwd_set + +from seahub.utils import get_user_repos class UserManager(object): def create_user(self, email, password=None, is_staff=False, is_active=False): @@ -141,7 +143,38 @@ class User(object): "Sends an e-mail to this User." from django.core.mail import send_mail send_mail(subject, message, from_email, [self.email]) - + + def remove_repo_passwds(self): + """ + Remove all repo decryption passwords stored on server. + """ + owned_repos, shared_repos, groups_repos = get_user_repos(self) + + def has_repo(repos, repo): + for r in repos: + if repo.id == r.id: + return True + return False + + passwd_setted_repos = [] + for r in owned_repos + groups_repos: + if not has_repo(passwd_setted_repos, r) and r.encrypted and \ + is_passwd_set(r.id, self.email): + passwd_setted_repos.append(r) + for r in shared_repos: + # For compatibility with diffrent fields names in Repo and + # SharedRepo objects. + r.id = r.repo_id + r.name = r.repo_name + r.desc = r.repo_desc + + if not has_repo(passwd_setted_repos, r) and r.encrypted and \ + is_passwd_set(r.id, self.email): + passwd_setted_repos.append(r) + + for r in passwd_setted_repos: + unset_repo_passwd(r.id, self.email) + class RegistrationBackend(object): """ A registration backend which follows a simple workflow: diff --git a/thirdpart/auth/__init__.py b/thirdpart/auth/__init__.py index c88774cfa3..76901f5266 100644 --- a/thirdpart/auth/__init__.py +++ b/thirdpart/auth/__init__.py @@ -85,9 +85,14 @@ def logout(request): """ Removes the authenticated user's ID from the request and flushes their session data. + Also remove all passwords used to decrypt repos. """ request.session.flush() if hasattr(request, 'user'): + # NOTE: must include `seahub` before `base` + from seahub.base.accounts import User + if isinstance(request.user, User): + request.user.remove_repo_passwds() from auth.models import AnonymousUser request.user = AnonymousUser() diff --git a/thirdpart/seaserv/__init__.py b/thirdpart/seaserv/__init__.py index 93b1f379e4..faf05d2c61 100644 --- a/thirdpart/seaserv/__init__.py +++ b/thirdpart/seaserv/__init__.py @@ -2,7 +2,7 @@ import service from service import ccnet_rpc, monitor_rpc, seafserv_rpc, \ seafserv_threaded_rpc, ccnet_threaded_rpc -from service import send_command, check_quota, web_get_access_token +from service import send_command, check_quota, web_get_access_token, unset_repo_passwd from service import get_emailusers from service import get_org_groups, get_personal_groups_by_user, \ get_group_repoids, get_personal_groups, \ diff --git a/thirdpart/seaserv/service.py b/thirdpart/seaserv/service.py index 15490d31a4..c61d12fa61 100644 --- a/thirdpart/seaserv/service.py +++ b/thirdpart/seaserv/service.py @@ -590,13 +590,6 @@ def check_permission(repo_id, user): ret = "" return ret -def is_passwd_set(repo_id, user): - try: - ret = seafserv_rpc.is_passwd_set(repo_id, user) - except SearpcError, e: - ret = -1 - return True if ret == 1 else False - def is_personal_repo(repo_id): """ Check whether repo is personal repo. @@ -738,3 +731,24 @@ def web_get_access_token(repo_id, obj_id, op, username): ret = '' return ret +# password management +def unset_repo_passwd(repo_id, user): + """ + Remove user password of a encrypt repo. + Arguments: + - `repo_id`: encrypt repo id + - `user`: username + """ + try: + ret = seafserv_threaded_rpc.unset_passwd(repo_id, user) + except SearpcError, e: + ret = -1 + return ret + +def is_passwd_set(repo_id, user): + try: + ret = seafserv_rpc.is_passwd_set(repo_id, user) + except SearpcError, e: + ret = -1 + return True if ret == 1 else False + diff --git a/utils.py b/utils.py index 91b3b69f92..ffdeda5534 100644 --- a/utils.py +++ b/utils.py @@ -175,7 +175,32 @@ def check_filename_with_rename(repo_id, parent_dir, filename): else: i += 1 +def get_user_repos(user): + """ + Get all repos that user can access, including owns, shared, and repo in + groups. + NOTE: collumn names in shared_repo struct are not same as owned or group + repos. + """ + email = user.username + if user.org: + # org context + org_id = user.org['org_id'] + owned_repos = list_org_repos_by_owner(org_id, email) + shared_repos = list_personal_shared_repos(email, 'to_email', -1, -1) + groups_repos = [] + for group in get_org_groups_by_user(org_id, email): + groups_repos += get_org_group_repos(org_id, group.id, email) + else: + # personal context + owned_repos = list_personal_repos_by_owner(email) + shared_repos = list_personal_shared_repos(email, 'to_email', -1, -1) + groups_repos = [] + for group in get_personal_groups_by_user(email): + groups_repos += get_group_repos(group.id, email) + return (owned_repos, shared_repos, groups_repos) + def get_accessible_repos(request, repo): """Get all repos the current user can access when coping/moving files online. If the repo is encrypted, then files can only be copied/moved @@ -200,23 +225,7 @@ def get_accessible_repos(request, repo): accessible_repos = [repo] return accessible_repos - email = request.user.username - - if request.user.org: - # org context - org_id = request.user.org['org_id'] - owned_repos = list_org_repos_by_owner(org_id, email) - shared_repos = list_personal_shared_repos(email, 'to_email', -1, -1) - groups_repos = [] - for group in get_org_groups_by_user(org_id, email): - groups_repos += get_org_group_repos(org_id, group.id, email) - else: - # personal context - owned_repos = list_personal_repos_by_owner(email) - shared_repos = list_personal_shared_repos(email, 'to_email', -1, -1) - groups_repos = [] - for group in get_personal_groups_by_user(email): - groups_repos += get_group_repos(group.id, email) + owned_repos, shared_repos, groups_repos = get_user_repos(request.user) def has_repo(repos, repo): for r in repos: