1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-07-17 16:52:09 +00:00
seahub/seahub/api2/endpoints/repo_set_password.py
lian d2e79aee73
support to change/reset password for department repo (#4673)
Co-authored-by: lian <lian@seafile.com>
2020-09-19 20:47:43 +08:00

182 lines
7.0 KiB
Python

# Copyright (c) 2012-2016 Seafile Ltd.
import logging
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from django.utils.translation import ugettext as _
from seaserv import seafile_api, ccnet_api
from pysearpc import SearpcError
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error
from seahub.utils.repo import is_repo_owner, get_repo_owner, \
add_encrypted_repo_secret_key_to_database
from seahub.base.models import RepoSecretKey
from seahub.views import check_folder_permission
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.settings import ENABLE_RESET_ENCRYPTED_REPO_PASSWORD
logger = logging.getLogger(__name__)
class RepoSetPassword(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication )
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle,)
def post(self, request, repo_id):
""" Check if repo password is correct.
Permission checking:
1. User can access current repo.
"""
# argument check
password = request.data.get('password', None)
if not password:
error_msg = 'password invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# resource check
repo = seafile_api.get_repo(repo_id)
if not repo:
error_msg = 'Library %s not found.' % repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if not repo.encrypted:
error_msg = 'Library %s is not encrypted.' % repo_id
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# permission check
if not check_folder_permission(request, repo_id, '/'):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
# check the password is correct
try:
seafile_api.set_passwd(repo_id, request.user.username, password)
except SearpcError as e:
if e.msg == 'Bad arguments':
error_msg = 'Bad arguments'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
elif e.msg == 'Incorrect password':
error_msg = _('Wrong password')
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
elif e.msg == 'Internal server error':
error_msg = _('Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
error_msg = _('Decrypt library error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if ENABLE_RESET_ENCRYPTED_REPO_PASSWORD:
add_encrypted_repo_secret_key_to_database(repo_id, password)
return Response({'success': True})
def put(self, request, repo_id):
""" Change/Init repo password.
Permission checking:
1. repo owner
"""
# argument check
operation = request.data.get('operation', 'change-password')
operation = operation.lower()
if operation not in ('change-password', 'reset-password', 'can-reset-password'):
error_msg = 'operation invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# resource check
repo = seafile_api.get_repo(repo_id)
if not repo:
error_msg = 'Library %s not found.' % repo_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if not repo.encrypted:
error_msg = 'Library %s is not encrypted.' % repo_id
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# permission check
username = request.user.username
repo_owner = get_repo_owner(request, repo_id)
if '@seafile_group' in repo_owner:
group_id = email2nickname(repo_owner)
if not ccnet_api.check_group_staff(int(group_id), username):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
else:
if username != repo_owner:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if operation == 'change-password':
old_password = request.data.get('old_password', None)
if not old_password:
error_msg = 'old_password invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
new_password = request.data.get('new_password', None)
if not new_password:
error_msg = 'new_password invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try:
seafile_api.change_repo_passwd(repo_id, old_password, new_password, username)
except Exception as e:
if e.msg == 'Incorrect password':
error_msg = _('Wrong old password')
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
else:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if ENABLE_RESET_ENCRYPTED_REPO_PASSWORD:
add_encrypted_repo_secret_key_to_database(repo_id, new_password)
if operation == 'can-reset-password':
if not ENABLE_RESET_ENCRYPTED_REPO_PASSWORD:
error_msg = 'Feature disabled.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if not RepoSecretKey.objects.get_secret_key(repo_id):
return Response({'allowed': False})
else:
return Response({'allowed': True})
if operation == 'reset-password':
if not ENABLE_RESET_ENCRYPTED_REPO_PASSWORD:
error_msg = 'Feature disabled.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
new_password = request.data.get('new_password', None)
if not new_password:
error_msg = 'new_password invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
secret_key = RepoSecretKey.objects.get_secret_key(repo_id)
if not secret_key:
error_msg = _("Can not reset this library's password.")
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try:
seafile_api.reset_repo_passwd(repo_id, username, secret_key, new_password)
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
return Response({'success': True})