def is_group_member(group_id, email, in_structure=None): group_id = int(group_id) if in_structure in (True, False): return ccnet_api.is_group_user(group_id, email, in_structure) group = ccnet_api.get_group(group_id) if group.parent_group_id == 0: # -1: top address book group # 0: group not in address book # >0: sub group in address book # if `in_structure` is False, NOT check sub groups in address book return ccnet_api.is_group_user(group_id, email, in_structure=False) else: return ccnet_api.is_group_user(group_id, email)
def post(self, request, group_id): """ Bulk add group members. Permission checking: 1. only admin can perform this action. """ # argument check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) emails = request.POST.getlist('email', '') if not emails: error_msg = 'Email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) result = {} result['failed'] = [] result['success'] = [] emails_need_add = [] for email in emails: try: User.objects.get(email=email) except User.DoesNotExist: result['failed'].append({ 'email': email, 'error_msg': 'User %s not found.' % email }) continue if ccnet_api.is_group_user(group_id, email): result['failed'].append({ 'email': email, 'error_msg': 'User %s is already a group member.' % email }) continue emails_need_add.append(email) # Add user to group. for email in emails_need_add: try: ccnet_api.group_add_member(group_id, group.creator_name, email) member_info = get_group_member_info(request, group_id, email) result['success'].append(member_info) except Exception as e: logger.error(e) result['failed'].append({ 'email': email, 'error_msg': 'Internal Server Error' }) return Response(result)
def put(self, request, repo_id, format=None): """ transfer a library Permission checking: 1. only admin can perform this action. """ 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) new_owner = request.data.get('owner', None) if not new_owner: error_msg = 'owner invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: new_owner_obj = User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not new_owner_obj.permissions.can_add_repo(): error_msg = 'Transfer failed: role of %s is %s, can not add library.' % \ (new_owner, new_owner_obj.role) return api_error(status.HTTP_403_FORBIDDEN, error_msg) if MULTI_TENANCY: try: if seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id) > 0: error_msg = 'Can not transfer organization library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if ccnet_api.get_orgs_by_user(new_owner): error_msg = 'Can not transfer library to organization user %s' % new_owner return api_error(status.HTTP_403_FORBIDDEN, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_owner = seafile_api.get_repo_owner(repo_id) # get repo shared to user/group list shared_users = seafile_api.list_repo_shared_to(repo_owner, repo_id) shared_groups = seafile_api.list_repo_shared_group_by_user( repo_owner, repo_id) # get all pub repos pub_repos = [] if not request.cloud_mode: pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner) # transfer repo seafile_api.set_repo_owner(repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.share_repo(repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not ccnet_api.is_group_user(shared_group_id, new_owner): continue seafile_api.set_group_repo(repo_id, shared_group_id, new_owner, shared_group.perm) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission) break # send admin operation log signal admin_op_detail = { "id": repo_id, "name": repo.name, "from": repo_owner, "to": new_owner, } admin_operation.send(sender=None, admin_name=request.user.username, operation=REPO_TRANSFER, detail=admin_op_detail) repo = seafile_api.get_repo(repo_id) repo_info = get_repo_info(repo) return Response(repo_info)
def is_group_member(group_id, email): return ccnet_api.is_group_user(int(group_id), email)
def put(self, request, org_id, repo_id): """Transfer an organization library """ new_owner = request.data.get('email', None) if not new_owner: error_msg = 'Email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_email(new_owner): error_msg = 'Email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) org_id = int(org_id) if not ccnet_api.get_org_by_id(org_id): error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission checking if not org_user_exists(org_id, new_owner): error_msg = 'User %s not in org %s.' % (new_owner, org_id) return api_error(status.HTTP_404_NOT_FOUND, error_msg) 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 is_org_repo(org_id, repo_id): error_msg = 'Library %s not in org %s.' % (repo_id, org_id) return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_owner = seafile_api.get_org_repo_owner(repo_id) # get repo shared to user/group list shared_users = seafile_api.list_org_repo_shared_to( org_id, repo_owner, repo_id) shared_groups = seafile_api.list_org_repo_shared_group( org_id, repo_owner, repo_id) # get all pub repos pub_repos = seafile_api.list_org_inner_pub_repos_by_owner( org_id, repo_owner) seafile_api.set_org_repo_owner(org_id, repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.org_share_repo(org_id, repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not ccnet_api.is_group_user(shared_group_id, new_owner): continue seafile_api.add_org_group_repo(repo_id, org_id, shared_group_id, new_owner, shared_group.perm) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.set_org_inner_pub_repo(org_id, repo_id, pub_repo.permission) break repo_info = {} repo_info['owner_email'] = new_owner repo_info['owner_name'] = email2nickname(new_owner) repo_info['encrypted'] = repo.encrypted repo_info['repo_id'] = repo.repo_id repo_info['repo_name'] = repo.name repo_info['is_department_repo'] = False repo_info['group_id'] = '' return Response(repo_info)
def post(self, request): """import department from dingtalk """ if not ENABLE_DINGTALK: error_msg = 'Feature is not enabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') # argument check department_id = request.data.get('department_id') try: department_id = int(department_id) except Exception as e: logger.error(e) error_msg = 'department_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) access_token = dingtalk_get_access_token() if not access_token: error_msg = '获取钉钉组织架构失败' return api_error(status.HTTP_404_NOT_FOUND, error_msg) # get department list # https://developers.dingtalk.com/document/app/obtain-the-department-list data = {'access_token': access_token, 'id': department_id} current_department_resp_json = requests.get(DINGTALK_DEPARTMENT_GET_DEPARTMENT_URL, params=data).json() current_department_list = [current_department_resp_json] sub_department_resp_json = requests.get(DINGTALK_DEPARTMENT_LIST_DEPARTMENT_URL, params=data).json() sub_department_list = sub_department_resp_json.get('department', []) department_list = current_department_list + sub_department_list department_list = sorted(department_list, key=lambda x:x['id']) # get department user list data = { 'access_token': access_token, 'department_id': department_id, 'offset': 0, 'size': DINGTALK_DEPARTMENT_USER_SIZE, } user_resp_json = requests.get(DINGTALK_DEPARTMENT_GET_DEPARTMENT_USER_LIST_URL, params=data).json() api_user_list = user_resp_json.get('userlist', []) # main success = list() failed = list() department_map_to_group_dict = dict() for index, department_obj in enumerate(department_list): # check department argument new_group_name = department_obj.get('name') department_obj_id = department_obj.get('id') parent_department_id = department_obj.get('parentid', 0) if department_obj_id is None or not new_group_name or not validate_group_name(new_group_name): failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '部门参数错误') failed.append(failed_msg) continue # check parent group if index == 0: parent_group_id = -1 else: parent_group_id = department_map_to_group_dict.get(parent_department_id) if parent_group_id is None: failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '父级部门不存在') failed.append(failed_msg) continue # check department exist exist_department = ExternalDepartment.objects.get_by_provider_and_outer_id( DINGTALK_PROVIDER, department_obj_id) if exist_department: department_map_to_group_dict[department_obj_id] = exist_department.group_id failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '部门已存在') failed.append(failed_msg) continue # import department try: group_id = ccnet_api.create_group( new_group_name, DEPARTMENT_OWNER, parent_group_id=parent_group_id) seafile_api.set_group_quota(group_id, -2) ExternalDepartment.objects.create( group_id=group_id, provider=DINGTALK_PROVIDER, outer_id=department_obj_id, ) department_map_to_group_dict[department_obj_id] = group_id success_msg = self._api_department_success_msg( department_obj_id, new_group_name, group_id) success.append(success_msg) except Exception as e: logger.error(e) failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '部门导入失败') failed.append(failed_msg) # todo filter ccnet User database social_auth_queryset = SocialAuthUser.objects.filter(provider='dingtalk') # import api_user for api_user in api_user_list: uid = api_user.get('unionid', '') api_user['contact_email'] = api_user['email'] api_user_name = api_user.get('name') # determine the user exists if social_auth_queryset.filter(uid=uid).exists(): email = social_auth_queryset.get(uid=uid).username else: # create user email = gen_user_virtual_id() try: User.objects.create_user(email) SocialAuthUser.objects.add(email, 'dingtalk', uid) except Exception as e: logger.error(e) failed_msg = self._api_user_failed_msg( '', api_user_name, department_id, '导入用户失败') failed.append(failed_msg) continue # bind user to department api_user_department_list = api_user.get('department') for department_obj_id in api_user_department_list: group_id = department_map_to_group_dict.get(department_obj_id) if group_id is None: # the api_user also exist in the brother department which not import continue if ccnet_api.is_group_user(group_id, email, in_structure=False): failed_msg = self._api_user_failed_msg( email, api_user_name, department_obj_id, '部门成员已存在') failed.append(failed_msg) continue try: ccnet_api.group_add_member(group_id, DEPARTMENT_OWNER, email) success_msg = self._api_user_success_msg( email, api_user_name, department_obj_id, group_id) success.append(success_msg) except Exception as e: logger.error(e) failed_msg = self._api_user_failed_msg( email, api_user_name, department_id, '导入部门成员失败') failed.append(failed_msg) try: update_dingtalk_user_info(email, api_user.get('name'), api_user.get('contact_email'), api_user.get('avatar')) except Exception as e: logger.error(e) return Response({ 'success': success, 'failed': failed, })
def add_admin_to_group(self): ccnet_api.group_add_member( self.group.id, self.user.username, self.admin.username) assert ccnet_api.is_group_user(self.group.id, self.admin.username)
def post(self, request): # argument check operation = request.data.get('operation') # operation could be `share`, `delete`, `transfer` # we now only use `share` if not operation or operation not in ('share'): error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) result = {} result['failed'] = [] result['success'] = [] username = request.user.username repo_id_list = request.data.getlist('repo_id') valid_repo_id_list = [] # filter out invalid repo id for repo_id in repo_id_list: if not seafile_api.get_repo(repo_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Library %s not found.' % repo_id }) continue if is_org_context(request): org_id = request.user.org.org_id org_repo_owner = seafile_api.get_org_repo_owner(repo_id) if not username == org_repo_owner: result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Permission denied.' }) continue else: if not seafile_api.is_repo_owner(username, repo_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Permission denied.' }) continue valid_repo_id_list.append(repo_id) # share repo if operation == 'share': share_type = request.data.get('share_type') if share_type != 'user' and share_type != 'group': error_msg = 'share_type invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) permission = request.data.get('permission', 'rw') if permission not in ('r', 'rw'): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # share repo to user if share_type == 'user': to_username = request.data.get('username', None) if not to_username: error_msg = 'username invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=to_username) except User.DoesNotExist: error_msg = 'User %s not found.' % to_username return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if to_user is an org user try: org_of_to_user = ccnet_api.get_orgs_by_user(to_username) except Exception as e: logger.debug(e) org_of_to_user = [] if is_org_context(request): org_id = request.user.org.org_id org_name = request.user.org.org_name if len(org_of_to_user ) == 0 or org_id != org_of_to_user[0].org_id: error_msg = 'User %s is not member of organization %s.' \ % (to_username, org_name) return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if len(org_of_to_user) >= 1: error_msg = 'User %s is member of organization %s.' \ % (to_username, org_of_to_user[0].org_name) return api_error(status.HTTP_403_FORBIDDEN, error_msg) for repo_id in valid_repo_id_list: if self.has_shared_to_user(request, repo_id, to_username): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'This item has been shared to %s.' % to_username }) continue try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_add_share( org_id, repo_id, username, to_username, permission) else: seafile_api.share_repo(repo_id, username, to_username, permission) # send a signal when sharing repo successful repo = seafile_api.get_repo(repo_id) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_username, repo=repo) result['success'].append({ "repo_id": repo_id, "username": to_username, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, to_username, repo_id, '/', permission) except Exception as e: logger.error(e) result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Internal Server Error' }) # share repo to group if share_type == 'group': to_group_id = request.data.get('group_id', None) if not to_group_id: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: to_group_id = int(to_group_id) except ValueError: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) group = ccnet_api.get_group(to_group_id) if not group: error_msg = 'Group %s not found.' % to_group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) group_name = group.group_name if not ccnet_api.is_group_user(to_group_id, username): error_msg = 'User %s is not member of group %s.' % ( username, group_name) return api_error(status.HTTP_403_FORBIDDEN, error_msg) for repo_id in valid_repo_id_list: if self.has_shared_to_group(request, repo_id, to_group_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'This item has been shared to %s.' % group_name }) continue try: if is_org_context(request): org_id = request.user.org.org_id seafile_api.add_org_group_repo( repo_id, org_id, to_group_id, username, permission) else: seafile_api.set_group_repo(repo_id, to_group_id, username, permission) # send a signal when sharing repo successful repo = seafile_api.get_repo(repo_id) share_repo_to_group_successful.send( sender=None, from_user=username, group_id=to_group_id, repo=repo) result['success'].append({ "repo_id": repo_id, "group_id": to_group_id, "group_name": group_name, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, to_group_id, repo_id, '/', permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Internal Server Error' }) return Response(result)
def put(self, request, repo_id, format=None): username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id) path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path) share_type = request.data.get('share_type') if share_type != 'user' and share_type != 'group': return api_error(status.HTTP_400_BAD_REQUEST, 'share_type invalid.') repo_owner = self.get_repo_owner(request, repo_id) if repo_owner != username and not is_repo_admin(username, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') permission = request.data.get('permission', PERMISSION_READ) if permission not in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN ]: return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') result = {} result['failed'] = [] result['success'] = [] if share_type == 'user': share_to_users = request.data.getlist('username') for to_user in share_to_users: if not is_valid_username(to_user): result['failed'].append({ 'email': to_user, 'error_msg': _(u'username invalid.') }) continue try: User.objects.get(email=to_user) except User.DoesNotExist: result['failed'].append({ 'email': to_user, 'error_msg': _(u'User %s not found.') % to_user }) continue if self.has_shared_to_user(request, repo_id, path, to_user): result['failed'].append({ 'email': to_user, 'error_msg': _(u'This item has been shared to %s.') % to_user }) continue try: org_id = None if is_org_context(request): org_id = request.user.org.org_id if not is_org_user(to_user, int(org_id)): org_name = request.user.org.org_name error_msg = 'User %s is not member of organization %s.' \ % (to_user, org_name) result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue # when calling seafile API to share authority related functions, change the uesrname to repo owner. repo_owner = seafile_api.get_org_repo_owner(repo_id) # can't share to owner if to_user == repo_owner: error_msg = "Library can not be shared to owner" return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_dir_to_user(repo, path, repo_owner, username, to_user, permission, org_id) else: if is_org_user(to_user): error_msg = 'User %s is a member of organization.' % to_user result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue repo_owner = seafile_api.get_repo_owner(repo_id) # can't share to owner if to_user == repo_owner: error_msg = "Library can not be shared to owner" return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_dir_to_user(repo, path, repo_owner, username, to_user, permission, None) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) # send a signal when sharing repo successful share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=repo, path=path, org_id=org_id) send_perm_audit_msg('add-repo-perm', username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'email': to_user, 'error_msg': 'Internal Server Error' }) continue if share_type == 'group': group_ids = request.data.getlist('group_id') for gid in group_ids: try: gid = int(gid) except ValueError: result['failed'].append( {'error_msg': 'group_id %s invalid.' % gid}) continue group = ccnet_api.get_group(gid) if not group: result['failed'].append( {'error_msg': 'Group %s not found' % gid}) continue if not config.ENABLE_SHARE_TO_ALL_GROUPS and \ not ccnet_api.is_group_user(gid, username): result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Permission denied.' }) continue if self.has_shared_to_group(request, repo_id, path, gid): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _(u'This item has been shared to %s.') % group.group_name }) continue try: org_id = None if is_org_context(request): # when calling seafile API to share authority related functions, change the uesrname to repo owner. repo_owner = seafile_api.get_org_repo_owner(repo_id) org_id = request.user.org.org_id share_dir_to_group(repo, path, repo_owner, username, gid, permission, org_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) share_dir_to_group(repo, path, repo_owner, username, gid, permission, None) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo, path=path, org_id=org_id) send_perm_audit_msg('add-repo-perm', username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Internal Server Error' }) continue return HttpResponse(json.dumps(result), status=200, content_type=json_content_type)
def org_repo_transfer(request): """Transfer a repo to others. """ if request.method != 'POST': raise Http404 repo_id = request.POST.get('repo_id', None) new_owner = request.POST.get('email', None) next = request.META.get('HTTP_REFERER', reverse(org_repo_admin)) if not repo_id and not new_owner: messages.error(request, 'Failed to transfer, invalid arguments.') return HttpResponseRedirect(next) # permission checking org_id = request.user.org.org_id if not org_user_exists(org_id, new_owner) or \ not is_valid_username(new_owner): messages.error(request, 'Failed to transfer, user does not exist.') return HttpResponseRedirect(next) if not is_org_repo(org_id, repo_id): messages.error(request, 'Failed to transfer, library does not exist.') return HttpResponseRedirect(next) repo_owner = seafile_api.get_org_repo_owner(repo_id) # get repo shared to user/group list shared_users = seafile_api.list_org_repo_shared_to(org_id, repo_owner, repo_id) shared_groups = seafile_api.list_org_repo_shared_group( org_id, repo_owner, repo_id) # get all pub repos pub_repos = seaserv.seafserv_threaded_rpc.list_org_inner_pub_repos_by_owner( org_id, repo_owner) seafile_api.set_org_repo_owner(org_id, repo_id, new_owner) messages.success(request, _(u'Successfully transfered 1 item.')) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seaserv.seafserv_threaded_rpc.org_add_share(org_id, repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not ccnet_api.is_group_user(shared_group_id, new_owner): continue seafile_api.add_org_group_repo(repo_id, org_id, shared_group_id, new_owner, shared_group.perm) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo( org_id, repo_id, pub_repo.permission) break return HttpResponseRedirect(next)
def has_permission(self, request, view, obj=None): group_id = int(view.kwargs.get('group_id', '')) username = request.user.username if request.user else '' return True if ccnet_api.is_group_user(group_id, username) else False
def add_admin_to_group(self): ccnet_api.group_add_member(self.group.id, self.user.username, self.admin.username) assert ccnet_api.is_group_user(self.group.id, self.admin.username)
def put(self, request, repo_id, format=None): username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id) path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path) share_type = request.data.get('share_type') if share_type != 'user' and share_type != 'group': return api_error(status.HTTP_400_BAD_REQUEST, 'share_type invalid.') if share_type == 'user': if username != self.get_repo_owner(request, repo_id) and \ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') else: if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') permission = request.data.get('permission', PERMISSION_READ) if permission not in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN ]: return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') result = {} result['failed'] = [] result['success'] = [] if share_type == 'user': share_to_users = request.data.getlist('username') for to_user in share_to_users: if not is_valid_username(to_user): result['failed'].append({ 'email': to_user, 'error_msg': _(u'username invalid.') }) continue try: User.objects.get(email=to_user) except User.DoesNotExist: result['failed'].append({ 'email': to_user, 'error_msg': _(u'User %s not found.') % to_user }) continue if self.has_shared_to_user(request, repo_id, path, to_user): result['failed'].append({ 'email': to_user, 'error_msg': _(u'This item has been shared to %s.') % to_user }) continue try: extra_share_permission = '' if permission == PERMISSION_ADMIN: extra_share_permission = permission permission = PERMISSION_READ_WRITE if is_org_context(request): username = seafile_api.get_org_repo_owner(repo_id) org_id = request.user.org.org_id if not is_org_user(to_user, int(org_id)): org_name = request.user.org.org_name error_msg = 'User %s is not member of organization %s.' \ % (to_user, org_name) result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue if path == '/': seaserv.seafserv_threaded_rpc.org_add_share( org_id, repo_id, username, to_user, permission) else: sub_repo_id = seafile_api.org_share_subdir_to_user( org_id, repo_id, path, username, to_user, permission) else: if is_org_user(to_user): error_msg = 'User %s is a member of organization.' % to_user result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue username = seafile_api.get_repo_owner(repo_id) if path == '/': seafile_api.share_repo(repo_id, username, to_user, permission) else: sub_repo_id = seafile_api.share_subdir_to_user( repo_id, path, username, to_user, permission) if path == '/' and extra_share_permission == PERMISSION_ADMIN: ExtraSharePermission.objects.create_share_permission( repo_id, to_user, extra_share_permission) # send a signal when sharing repo successful if path == '/': share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=repo) else: sub_repo = seafile_api.get_repo(sub_repo_id) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=sub_repo) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": permission, "is_admin": extra_share_permission == PERMISSION_ADMIN }) send_perm_audit_msg('add-repo-perm', username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'email': to_user, 'error_msg': 'Internal Server Error' }) continue if share_type == 'group': group_ids = request.data.getlist('group_id') for gid in group_ids: try: gid = int(gid) except ValueError: result['failed'].append( {'error_msg': _(u'group_id %s invalid.') % gid}) continue group = ccnet_api.get_group(gid) if not group: result['failed'].append( {'error_msg': _(u'Group %s not found') % gid}) continue if not config.ENABLE_SHARE_TO_ALL_GROUPS and \ not ccnet_api.is_group_user(gid, username): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _(u'Permission denied.') }) continue if self.has_shared_to_group(request, repo_id, path, gid): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _(u'This item has been shared to %s.') % group.group_name }) continue try: if is_org_context(request): org_id = request.user.org.org_id if path == '/': seafile_api.add_org_group_repo( repo_id, org_id, gid, username, permission) else: sub_repo_id = seafile_api.org_share_subdir_to_group( org_id, repo_id, path, username, gid, permission) else: if path == '/': seafile_api.set_group_repo(repo_id, gid, username, permission) else: sub_repo_id = seafile_api.share_subdir_to_group( repo_id, path, username, gid, permission) if path == '/': share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo) else: sub_repo = seafile_api.get_repo(sub_repo_id) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=sub_repo) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Internal Server Error' }) continue return HttpResponse(json.dumps(result), status=200, content_type=json_content_type)
def post(self, request): """import department from work weixin permission: IsProVersion """ if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') # argument check department_id = request.data.get('work_weixin_department_id') try: department_id = int(department_id) except Exception as e: logger.error(e) error_msg = 'work_weixin_department_ids invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # is pro version and work weixin check if not IsProVersion or not admin_work_weixin_departments_check(): error_msg = 'Feature is not enabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) access_token = get_work_weixin_access_token() if not access_token: logger.error('can not get work weixin access_token') error_msg = '获取企业微信组织架构失败' return api_error(status.HTTP_404_NOT_FOUND, error_msg) # list departments from work weixin api_department_list = self._list_departments_from_work_weixin( access_token, department_id) if api_department_list is None: error_msg = '获取企业微信组织架构失败' return api_error(status.HTTP_404_NOT_FOUND, error_msg) # list department members from work weixin api_user_list = self._list_department_members_from_work_weixin( access_token, department_id) if api_user_list is None: error_msg = '获取企业微信组织架构成员失败' return api_error(status.HTTP_404_NOT_FOUND, error_msg) # main success = list() failed = list() department_map_to_group_dict = dict() for index, department_obj in enumerate(api_department_list): # check department argument new_group_name = department_obj.get('name') department_obj_id = department_obj.get('id') if department_obj_id is None or not new_group_name or not validate_group_name( new_group_name): failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '部门参数错误') failed.append(failed_msg) continue # check parent group if index == 0: parent_group_id = -1 else: parent_department_id = department_obj.get('parentid') parent_group_id = department_map_to_group_dict.get( parent_department_id) if parent_group_id is None: failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '父级部门不存在') failed.append(failed_msg) continue # check department exist by group name exist, exist_group = self._admin_check_group_name_conflict( new_group_name) if exist: department_map_to_group_dict[ department_obj_id] = exist_group.id failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '部门已存在') failed.append(failed_msg) continue # import department try: group_id = ccnet_api.create_group( new_group_name, DEPARTMENT_OWNER, parent_group_id=parent_group_id) seafile_api.set_group_quota(group_id, -2) department_map_to_group_dict[department_obj_id] = group_id success_msg = self._api_department_success_msg( department_obj_id, new_group_name, group_id) success.append(success_msg) except Exception as e: logger.error(e) failed_msg = self._api_department_failed_msg( department_obj_id, new_group_name, '部门导入失败') failed.append(failed_msg) # todo filter ccnet User database social_auth_queryset = SocialAuthUser.objects.filter( provider=WORK_WEIXIN_PROVIDER, uid__contains=WORK_WEIXIN_UID_PREFIX) # import api_user for api_user in api_user_list: uid = WORK_WEIXIN_UID_PREFIX + api_user.get('userid', '') api_user['contact_email'] = api_user['email'] api_user_name = api_user.get('name') # determine the user exists if social_auth_queryset.filter(uid=uid).exists(): email = social_auth_queryset.get(uid=uid).username else: # create user email = gen_user_virtual_id() create_user_success = _import_user_from_work_weixin( email, api_user) if not create_user_success: failed_msg = self._api_user_failed_msg( '', api_user_name, department_id, '导入用户失败') failed.append(failed_msg) continue # bind user to department api_user_department_list = api_user.get('department') for department_obj_id in api_user_department_list: group_id = department_map_to_group_dict.get(department_obj_id) if group_id is None: # the api_user also exist in the brother department which not import continue if ccnet_api.is_group_user(group_id, email): failed_msg = self._api_user_failed_msg( email, api_user_name, department_obj_id, '部门成员已存在') failed.append(failed_msg) continue try: ccnet_api.group_add_member(group_id, DEPARTMENT_OWNER, email) success_msg = self._api_user_success_msg( email, api_user_name, department_obj_id, group_id) success.append(success_msg) except Exception as e: logger.error(e) failed_msg = self._api_user_failed_msg( email, api_user_name, department_id, '导入部门成员失败') failed.append(failed_msg) return Response({ 'success': success, 'failed': failed, })
def put(self, request, repo_id, format=None): """ transfer a library Permission checking: 1. only admin can perform this action. """ 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) new_owner = request.data.get('owner', None) if not new_owner: error_msg = 'owner invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) if MULTI_TENANCY: try: if seafserv_threaded_rpc.get_org_id_by_repo_id(repo_id) > 0: error_msg = 'Can not transfer organization library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if ccnet_api.get_orgs_by_user(new_owner): error_msg = 'Can not transfer library to organization user %s' % new_owner return api_error(status.HTTP_403_FORBIDDEN, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_owner = seafile_api.get_repo_owner(repo_id) # get repo shared to user/group list shared_users = seafile_api.list_repo_shared_to( repo_owner, repo_id) shared_groups = seafile_api.list_repo_shared_group_by_user( repo_owner, repo_id) # get all pub repos pub_repos = [] if not request.cloud_mode: pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner) # transfer repo seafile_api.set_repo_owner(repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.share_repo(repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not ccnet_api.is_group_user(shared_group_id, new_owner): continue seafile_api.set_group_repo(repo_id, shared_group_id, new_owner, shared_group.perm) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission) break repo = seafile_api.get_repo(repo_id) repo_info = get_repo_info(repo) return Response(repo_info)