Beispiel #1
0
def get_group_info(group_id, show_size=False):
    group = ccnet_api.get_group(group_id)
    isoformat_timestr = timestamp_to_isoformat_timestr(group.timestamp)
    group_info = {
        "id": group.id,
        "name": group.group_name,
        "owner": group.creator_name,
        "owner_name": email2nickname(group.creator_name),
        "created_at": isoformat_timestr,
        "quota":
        seafile_api.get_group_quota(group_id) if is_pro_version() else 0,
        "parent_group_id": group.parent_group_id if is_pro_version() else 0
    }
    if ccnet_api.is_org_group(group_id):
        org_id = ccnet_api.get_org_id_by_group(group_id)
        group_info['org_id'] = org_id
        if org_id:
            org = ccnet_api.get_org_by_id(org_id)
            if org:
                group_info['org_name'] = org.org_name

    if show_size:
        owner = '%s@seafile_group' % group_id
        workspace = Workspaces.objects.get_workspace_by_owner(owner)
        if workspace:
            repo = seafile_api.get_repo(workspace.repo_id)
            group_info['size'] = repo.size

    return group_info
Beispiel #2
0
def get_group_info(group_id):
    group = ccnet_api.get_group(group_id)
    isoformat_timestr = timestamp_to_isoformat_timestr(group.timestamp)
    group_info = {
        "id": group.id,
        "name": group.group_name,
        "owner": group.creator_name,
        "owner_name": email2nickname(group.creator_name),
        "created_at": isoformat_timestr,
        "quota": seafile_api.get_group_quota(group_id) if is_pro_version() else 0,
        "parent_group_id": group.parent_group_id if is_pro_version() else 0
    }

    return group_info
Beispiel #3
0
def libraries(request):
    """
    New URL to replace myhome
    """
    username = request.user.username

    # options
    if request.cloud_mode and request.user.org is None:
        allow_public_share = False
    else:
        allow_public_share = True
    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
    max_upload_file_size = get_max_upload_file_size()
    guide_enabled = UserOptions.objects.is_user_guide_enabled(username)
    if guide_enabled:
        create_default_library(request)

    folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
    can_add_pub_repo = True if is_org_repo_creation_allowed(request) else False

    if request.cloud_mode and request.user.org is not None:
        org_id = request.user.org.org_id
        joined_groups = seaserv.get_org_groups_by_user(org_id, username)
    else:
        joined_groups = seaserv.get_personal_groups_by_user(username)

    if joined_groups:
        joined_groups.sort(lambda x, y: cmp(x.group_name.lower(), y.group_name.lower()))

    return render_to_response('libraries.html', {
            "allow_public_share": allow_public_share,
            "guide_enabled": guide_enabled,
            "sub_lib_enabled": sub_lib_enabled,
            'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
            'enable_resumable_fileupload': settings.ENABLE_RESUMABLE_FILEUPLOAD,
            'max_number_of_files_for_fileupload': settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD,
            'enable_thumbnail': settings.ENABLE_THUMBNAIL,
            'thumbnail_default_size': settings.THUMBNAIL_DEFAULT_SIZE,
            'thumbnail_size_for_grid': settings.THUMBNAIL_SIZE_FOR_GRID,
            'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
            'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
            'max_upload_file_size': max_upload_file_size,
            'folder_perm_enabled': folder_perm_enabled,
            'is_pro': True if is_pro_version() else False,
            'file_audit_enabled': FILE_AUDIT_ENABLED,
            'can_add_pub_repo': can_add_pub_repo,
            'joined_groups': joined_groups,
            'library_templates': LIBRARY_TEMPLATES.keys() if \
                    isinstance(LIBRARY_TEMPLATES, dict) else []
            }, context_instance=RequestContext(request))
Beispiel #4
0
def libraries(request):
    """
    New URL to replace myhome
    """
    username = request.user.username

    # options
    if request.cloud_mode and request.user.org is None:
        allow_public_share = False
    else:
        allow_public_share = True
    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
    max_upload_file_size = get_max_upload_file_size()
    guide_enabled = UserOptions.objects.is_user_guide_enabled(username)
    if guide_enabled:
        create_default_library(request)

    folder_perm_enabled = True if is_pro_version(
    ) and ENABLE_FOLDER_PERM else False
    can_add_pub_repo = True if is_org_repo_creation_allowed(request) else False

    if request.cloud_mode and request.user.org is not None:
        org_id = request.user.org.org_id
        joined_groups = seaserv.get_org_groups_by_user(org_id, username)
    else:
        joined_groups = seaserv.get_personal_groups_by_user(username)

    if joined_groups:
        joined_groups.sort(
            lambda x, y: cmp(x.group_name.lower(), y.group_name.lower()))

    return render_to_response('libraries.html', {
        "allow_public_share": allow_public_share,
        "guide_enabled": guide_enabled,
        "sub_lib_enabled": sub_lib_enabled,
        'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
        'enable_resumable_fileupload': settings.ENABLE_RESUMABLE_FILEUPLOAD,
        'enable_thumbnail': settings.ENABLE_THUMBNAIL,
        'thumbnail_default_size': settings.THUMBNAIL_DEFAULT_SIZE,
        'thumbnail_size_for_grid': settings.THUMBNAIL_SIZE_FOR_GRID,
        'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
        'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
        'max_upload_file_size': max_upload_file_size,
        'folder_perm_enabled': folder_perm_enabled,
        'is_pro': True if is_pro_version() else False,
        'file_audit_enabled': FILE_AUDIT_ENABLED,
        'can_add_pub_repo': can_add_pub_repo,
        'joined_groups': joined_groups,
    },
                              context_instance=RequestContext(request))
Beispiel #5
0
def get_group_info(group_id):
    group = ccnet_api.get_group(group_id)
    isoformat_timestr = timestamp_to_isoformat_timestr(group.timestamp)
    group_info = {
        "id": group.id,
        "name": group.group_name,
        "owner": group.creator_name,
        "created_at": isoformat_timestr,
        "quota":
        seafile_api.get_group_quota(group_id) if is_pro_version() else 0,
        "parent_group_id": group.parent_group_id if is_pro_version() else 0
    }

    return group_info
Beispiel #6
0
def user_number_over_limit(new_users=0):
    logger = logging.getLogger(__name__)
    if is_pro_version():
        try:
            # get license user limit
            license_dict = parse_license()
            max_users = int(license_dict.get('MaxUsers', 3))

            # get active user number
            active_db_users = ccnet_api.count_emailusers('DB')
            active_ldap_users = ccnet_api.count_emailusers('LDAP')
            active_users = active_db_users + active_ldap_users if \
                           active_ldap_users > 0 else active_db_users

            if new_users < 0:
                logger.debug('`new_users` must be greater or equal to 0.')
                return False
            elif new_users == 0:
                return active_users >= max_users
            else:
                return active_users + new_users > max_users

        except Exception as e:
            logger.error(e)
            return False
    else:
        return False
Beispiel #7
0
def get_group_info(request, group_id, avatar_size=GROUP_AVATAR_DEFAULT_SIZE):
    group = ccnet_api.get_group(group_id)
    try:
        avatar_url, is_default, date_uploaded = api_grp_avatar_url(group.id, avatar_size)
    except Exception as e:
        logger.error(e)
        avatar_url = get_default_group_avatar_url()

    isoformat_timestr = timestamp_to_isoformat_timestr(group.timestamp)
    group_info = {
        "id": group.id,
        "parent_group_id": group.parent_group_id,
        "name": group.group_name,
        "owner": group.creator_name,
        "created_at": isoformat_timestr,
        "avatar_url": request.build_absolute_uri(avatar_url),
        "admins": get_group_admins(group.id),
    }
    # parent_group_id = 0: non department group
    # parent_group_id = -1: top department group
    # parent_group_id = n(n > 0):  sub department group, n is parent group's id
    if group.parent_group_id != 0:
        group_info['group_quota'] = seafile_api.get_group_quota(group_id)

    group_info['group_quota_usage'] = ''
    if is_pro_version():
        if is_org_context(request):
            org_id = request.user.org.org_id
            group_info['group_quota_usage'] = seafile_api.org_get_group_quota_usage(org_id, group_id)
        else:
            group_info['group_quota_usage'] = seafile_api.get_group_quota_usage(group_id)

    return group_info
Beispiel #8
0
    def get(self, request):

        if not is_pro_version():
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # check the date format, should be like '2015-10-10'
        start = request.GET.get('start', None)
        end = request.GET.get('end', None)

        if not check_time_period_valid(start, end):
            error_msg = 'start or end date invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        result = []
        events = get_log_events_by_type_and_time('file_update', start, end)
        if events:
            for ev in events:
                tmp_repo = seafile_api.get_repo(ev.repo_id)
                tmp_repo_name = tmp_repo.name if tmp_repo else ''

                result.append({
                    'commit_id': ev.commit_id,
                    'repo_id': ev.repo_id,
                    'repo_name': tmp_repo_name,
                    'time': datetime_to_isoformat_timestr(ev.timestamp),
                    'file_operation': ev.file_oper,
                    'user_name': email2nickname(ev.user),
                    'user_email': ev.user
                })

        return Response(result)
Beispiel #9
0
    def get(self, request, format=None):
        info = {
            'version':
            settings.SEAFILE_VERSION,
            'encrypted_library_version':
            settings.ENCRYPTED_LIBRARY_VERSION
            if settings.ENCRYPTED_LIBRARY_VERSION >= 3 else 2,
        }

        features = ['seafile-basic']

        if is_pro_version():
            features.append('seafile-pro')

        if HAS_OFFICE_CONVERTER:
            features.append('office-preview')

        if HAS_FILE_SEARCH:
            features.append('file-search')

        if config.DISABLE_SYNC_WITH_ANY_FOLDER:
            features.append('disable-sync-with-any-folder')

        if hasattr(settings, 'DESKTOP_CUSTOM_LOGO'):
            info['desktop-custom-logo'] = settings.MEDIA_URL + getattr(
                settings, 'DESKTOP_CUSTOM_LOGO')

        if hasattr(settings, 'DESKTOP_CUSTOM_BRAND'):
            info['desktop-custom-brand'] = getattr(settings,
                                                   'DESKTOP_CUSTOM_BRAND')

        info['features'] = features
        return info
Beispiel #10
0
def populate_user_permissions(user):
    if is_pro_version():
        from seahub_extra.auth_extra.utils import populate_user_permissions
        populate_user_permissions(user)
    else:
        # use default user permissions
        pass
Beispiel #11
0
def sysadmin_react_fake_view(request, **kwargs):

    try:
        expire_days = seafile_api.get_server_config_int('library_trash', 'expire_days')
    except Exception as e:
        logger.error(e)
        expire_days = -1

    multi_institution = getattr(dj_settings, 'MULTI_INSTITUTION', False)
    institutions = None
    if multi_institution:
        institutions = [inst.name for inst in Institution.objects.all()]

    return render(request, 'sysadmin/sysadmin_react_app.html', {
        'constance_enabled': dj_settings.CONSTANCE_ENABLED,
        'multi_tenancy': MULTI_TENANCY,
        'multi_institution': multi_institution,
        'institutions': institutions,
        'send_email_on_adding_system_member': SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER,
        'sysadmin_extra_enabled': True if is_pro_version() else False,
        'enable_guest_invitation': ENABLE_GUEST_INVITATION,
        'enable_terms_and_conditions': config.ENABLE_TERMS_AND_CONDITIONS,
        'enable_file_scan': ENABLE_FILE_SCAN,
        'enable_work_weixin': ENABLE_WORK_WEIXIN,
        'enable_dingtalk': ENABLE_DINGTALK,
        'enable_sys_admin_view_repo': ENABLE_SYS_ADMIN_VIEW_REPO,
        'trash_repos_expire_days': expire_days if expire_days > 0 else 30,
        'available_roles': get_available_roles(),
        'available_admin_roles': get_available_admin_roles(),
        'have_ldap': get_ldap_info(),
        'two_factor_auth_enabled': has_two_factor_auth(),
        'enable_share_link_report_abuse': ENABLE_SHARE_LINK_REPORT_ABUSE,
    })
Beispiel #12
0
def react_fake_view(request, **kwargs):
    folder_perm_enabled = True if is_pro_version(
    ) and ENABLE_FOLDER_PERM else False

    return render(
        request, "react_app.html", {
            'seafile_collab_server': SEAFILE_COLLAB_SERVER,
            'storages': get_library_storages(request),
            'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,
            'resumable_upload_file_block_size':
            settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE,
            'share_link_expire_days_default':
            settings.SHARE_LINK_EXPIRE_DAYS_DEFAULT,
            'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
            'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
            'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
            'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
            'enable_reset_encrypted_repo_password':
            ENABLE_RESET_ENCRYPTED_REPO_PASSWORD,
            'enableFileComment': settings.ENABLE_FILE_COMMENT,
            'is_email_configured': IS_EMAIL_CONFIGURED,
            'can_add_public_repo':
            request.user.permissions.can_add_public_repo(),
            'folder_perm_enabled': folder_perm_enabled,
            'file_audit_enabled': FILE_AUDIT_ENABLED
        })
Beispiel #13
0
    def get(self, request):

        if not is_pro_version():
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # check the date format, should be like '2015-10-10'
        start = request.GET.get('start', None)
        end = request.GET.get('end', None)

        if not check_time_period_valid(start, end):
            error_msg = 'start or end date invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        result = []
        events = get_log_events_by_type_and_time('file_audit', start, end)
        if events:
            for ev in events:
                tmp_repo = seafile_api.get_repo(ev.repo_id)
                tmp_repo_name = tmp_repo.name if tmp_repo else ''

                result.append({
                    'repo_id': ev.repo_id,
                    'repo_name': tmp_repo_name,
                    'time': datetime_to_isoformat_timestr(ev.timestamp),
                    'etype': ev.etype,
                    'ip': ev.ip,
                    'file_path': ev.file_path,
                    'etype': ev.etype,
                    'user_name': email2nickname(ev.user),
                    'user_email': ev.user
                })

        return Response(result)
Beispiel #14
0
def user_number_over_limit(new_users=0):
    logger = logging.getLogger(__name__)
    if is_pro_version():
        try:
            # get license user limit
            license_dict = parse_license()
            max_users = int(license_dict.get('MaxUsers', 3))

            # get active user number
            active_db_users = ccnet_api.count_emailusers('DB')
            active_ldap_users = ccnet_api.count_emailusers('LDAP')
            active_users = active_db_users + active_ldap_users if \
                           active_ldap_users > 0 else active_db_users

            if new_users < 0:
                logger.debug('`new_users` must be greater or equal to 0.')
                return False
            elif new_users == 0:
                return active_users >= max_users
            else:
                return active_users + new_users > max_users

        except Exception as e:
            logger.error(e)
            return False
    else:
        return False
Beispiel #15
0
def check_file_lock(repo_id, file_path, username):
    """ Check if file is locked to current user

    According to returned value of seafile_api.check_file_lock:
    0: not locked
    1: locked by other
    2: locked by me
    -1: error

    Return (is_locked, locked_by_me)
    """

    if not is_pro_version():
        return (False, False)

    return_value = seafile_api.check_file_lock(repo_id,
            file_path.lstrip('/'), username)

    if return_value == 0:
        return (False, False)
    elif return_value == 1:
        return (True , False)
    elif return_value == 2:
        return (True, True)
    else:
        raise SearpcError('check file lock error')
Beispiel #16
0
def sys_check_license(request):
    """Check seafile license expiration.
    """
    if not is_pro_version():
        raise Http404

    content_type = 'application/json; charset=utf-8'
    result = {}

    license_dict = parse_license()
    if license_dict:
        try:
            expiration = license_dict['Expiration']
        except KeyError as e:
            logger.error(e)
            result['error'] = str(e)
            return HttpResponse(json.dumps(result),
                                status=500,
                                content_type=content_type)

        struct_time = datetime.datetime.strptime(expiration, "%Y-%m-%d")
        expiration_timestamp = time.mktime(struct_time.timetuple())

        if time.time() > expiration_timestamp:
            # already expired
            result['already_expired'] = True
        elif time.time() + 30 * 24 * 60 * 60 > expiration_timestamp:
            # will be expired in 30 days
            result['to_be_expired'] = True

        result['expiration_date'] = expiration

    return HttpResponse(json.dumps(result), content_type=content_type)
Beispiel #17
0
def get_user_info(email):

    user = User.objects.get(email=email)
    d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email)
    profile = Profile.objects.get_profile_by_user(email)

    info = {}
    info['email'] = email
    info['name'] = email2nickname(email)
    info['contact_email'] = profile.contact_email if profile and profile.contact_email else ''
    info['login_id'] = profile.login_id if profile and profile.login_id else ''

    info['is_staff'] = user.is_staff
    info['is_active'] = user.is_active
    info['create_time'] = user.ctime
    info['reference_id'] = user.reference_id if user.reference_id else ''

    info['department'] = d_profile.department if d_profile else ''

    info['quota_total'] = seafile_api.get_user_quota(email)
    info['quota_usage'] = seafile_api.get_user_self_usage(email)

    info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)

    if is_pro_version():
        info['role'] = user.role

    return info
Beispiel #18
0
    def get(self, request):

        if not is_pro_version():
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # check the date format, should be like '2015-10-10'
        start = request.GET.get('start', None)
        end = request.GET.get('end', None)

        if not check_time_period_valid(start, end):
            error_msg = 'start or end date invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # Filtering a DateTimeField with dates won't include items on the last day,
        # because the bounds are interpreted as '0am on the given date'.
        end = end + ' 23:59:59'

        result = []
        from seahub_extra.sysadmin_extra.models import UserLoginLog
        logs = UserLoginLog.objects.filter(login_date__range=(start, end))
        for log in logs:
            result.append({
                'login_time': datetime_to_isoformat_timestr(log.login_date),
                'login_ip': log.login_ip,
                'name': email2nickname(log.username),
                'email':log.username
            })

        return Response(result)
Beispiel #19
0
    def _decorated(view, request, *args, **kwargs):
        if not is_pro_version() or not EVENTS_ENABLED:
            return api_error(status.HTTP_404_NOT_FOUND, 'Events not enabled.')
        start_time = request.GET.get("start", "")
        end_time = request.GET.get("end", "")
        if not start_time:
            error_msg = "Start time can not be empty"
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        if not end_time:
            error_msg = "End time can not be empty"
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        try:
            start_time = datetime.datetime.strptime(start_time,
                                                    "%Y-%m-%d %H:%M:%S")
        except:
            error_msg = "Start time %s invalid" % start_time
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        try:
            end_time = datetime.datetime.strptime(end_time,
                                                  "%Y-%m-%d %H:%M:%S")
        except:
            error_msg = "End time %s invalid" % end_time
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        return func(view, request, start_time, end_time, *args, **kwargs)
Beispiel #20
0
def update_user_info(request, user, password, is_active, is_staff, role,
                     nickname, login_id, contact_email, reference_id,
                     quota_total_mb, institution_name):

    # update basic user info
    if is_active is not None:
        user.is_active = is_active

    if password:
        user.set_password(password)

    if is_staff is not None:
        user.is_staff = is_staff

    # update user
    user.save()

    email = user.username

    # update additional user info
    if is_pro_version() and role:
        User.objects.update_role(email, role)

    if nickname is not None:
        Profile.objects.add_or_update(email, nickname)
        key = normalize_cache_key(nickname, NICKNAME_CACHE_PREFIX)
        cache.set(key, nickname, NICKNAME_CACHE_TIMEOUT)

    if login_id is not None:
        Profile.objects.add_or_update(email, login_id=login_id)

    if contact_email is not None:
        Profile.objects.add_or_update(email, contact_email=contact_email)
        key = normalize_cache_key(email, CONTACT_CACHE_PREFIX)
        cache.set(key, contact_email, CONTACT_CACHE_TIMEOUT)

    if reference_id is not None:
        if reference_id.strip():
            ccnet_api.set_reference_id(email, reference_id.strip())
        else:
            # remove reference id
            ccnet_api.set_reference_id(email, None)

    if institution_name is not None:
        Profile.objects.add_or_update(email, institution=institution_name)
        if institution_name == '':
            InstitutionAdmin.objects.filter(user=email).delete()

    if quota_total_mb:
        quota_total = int(quota_total_mb) * get_file_size_unit('MB')
        orgs = ccnet_api.get_orgs_by_user(email)
        try:
            if orgs:
                org_id = orgs[0].org_id
                seafile_api.set_org_user_quota(org_id, email, quota_total)
            else:
                seafile_api.set_user_quota(email, quota_total)
        except Exception as e:
            logger.error(e)
            seafile_api.set_user_quota(email, -1)
Beispiel #21
0
def react_fake_view(request, **kwargs):

    username = request.user.username
    guide_enabled = UserOptions.objects.is_user_guide_enabled(username)
    if guide_enabled:
        create_default_library(request)

    try:
        expire_days = seafile_api.get_server_config_int(
            'library_trash', 'expire_days')
    except Exception as e:
        logger.error(e)
        expire_days = -1

    folder_perm_enabled = True if is_pro_version(
    ) and ENABLE_FOLDER_PERM else False

    try:
        max_upload_file_size = seafile_api.get_server_config_int(
            'fileserver', 'max_upload_size')
    except Exception as e:
        logger.error(e)
        max_upload_file_size = -1

    return render(
        request, "react_app.html", {
            "guide_enabled": guide_enabled,
            'trash_repos_expire_days': expire_days if expire_days > 0 else 30,
            'dtable_web_server': DTABLE_WEB_SERVER,
            'max_upload_file_size': max_upload_file_size,
            'seafile_collab_server': SEAFILE_COLLAB_SERVER,
            'storages': get_library_storages(request),
            'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,
            'resumable_upload_file_block_size':
            settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE,
            'max_number_of_files_for_fileupload':
            settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD,
            'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT,
            'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN,
            'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX,
            'upload_link_expire_days_default': UPLOAD_LINK_EXPIRE_DAYS_DEFAULT,
            'upload_link_expire_days_min': UPLOAD_LINK_EXPIRE_DAYS_MIN,
            'upload_link_expire_days_max': UPLOAD_LINK_EXPIRE_DAYS_MAX,
            'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
            'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
            'enable_reset_encrypted_repo_password':
            ENABLE_RESET_ENCRYPTED_REPO_PASSWORD,
            'enableFileComment': settings.ENABLE_FILE_COMMENT,
            'is_email_configured': IS_EMAIL_CONFIGURED,
            'can_add_public_repo':
            request.user.permissions.can_add_public_repo(),
            'folder_perm_enabled': folder_perm_enabled,
            'file_audit_enabled': FILE_AUDIT_ENABLED,
            'custom_nav_items': json.dumps(CUSTOM_NAV_ITEMS),
            'enable_show_contact_email_when_search_user':
            settings.ENABLE_SHOW_CONTACT_EMAIL_WHEN_SEARCH_USER,
            'additional_share_dialog_note': ADDITIONAL_SHARE_DIALOG_NOTE,
            'additional_app_bottom_links': ADDITIONAL_APP_BOTTOM_LINKS,
            'additional_about_dialog_links': ADDITIONAL_ABOUT_DIALOG_LINKS
        })
Beispiel #22
0
    def delete(self):
        """
        When delete user, we should also delete group relationships.
        """
        if self.source == "DB":
            source = "DB"
        else:
            source = "LDAP"

        username = self.username

        orgs = []
        if is_pro_version():
            orgs = ccnet_api.get_orgs_by_user(username)

        # remove owned repos
        owned_repos = []
        if orgs:
            for org in orgs:
                owned_repos += seafile_api.get_org_owned_repo_list(
                    org.org_id, username)
        else:
            owned_repos += seafile_api.get_owned_repo_list(username)

        for r in owned_repos:
            seafile_api.remove_repo(r.id)

        # remove shared in repos
        shared_in_repos = []
        if orgs:
            for org in orgs:
                org_id = org.org_id
                shared_in_repos = seafile_api.get_org_share_in_repo_list(
                    org_id, username, -1, -1)

                for r in shared_in_repos:
                    seafile_api.org_remove_share(org_id, r.repo_id, r.user,
                                                 username)
        else:
            shared_in_repos = seafile_api.get_share_in_repo_list(
                username, -1, -1)
            for r in shared_in_repos:
                seafile_api.remove_share(r.repo_id, r.user, username)
        ExtraSharePermission.objects.filter(share_to=username).delete()

        # clear web api and repo sync token
        # when delete user
        try:
            clear_token(self.username)
        except Exception as e:
            logger.error(e)

        # remove current user from joined groups
        ccnet_api.remove_group_user(username)
        ccnet_api.remove_emailuser(source, username)
        Profile.objects.delete_profile_by_user(username)

        if settings.ENABLE_TERMS_AND_CONDITIONS:
            from termsandconditions.models import UserTermsAndConditions
            UserTermsAndConditions.objects.filter(username=username).delete()
Beispiel #23
0
    def get(self, request, email):
        """ return all groups user joined

        Permission checking:
        1. Admin user;
        """

        if not request.user.admin_permissions.can_manage_user():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        try:
            User.objects.get(email=email)
        except User.DoesNotExist as e:
            logger.error(e)
            error_msg = 'User %s not found.' % email
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        groups_info = []
        try:
            groups = ccnet_api.get_groups(email)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # Use dict to reduce memcache fetch cost in large for-loop.
        nickname_dict = {}
        creator_name_set = set([g.creator_name for g in groups])
        for e in creator_name_set:
            if e not in nickname_dict:
                nickname_dict[e] = email2nickname(e)

        for group in groups:
            isoformat_timestr = timestamp_to_isoformat_timestr(group.timestamp)
            group_info = {
                "id": group.id,
                "name": group.group_name,
                "owner_email": group.creator_name,
                "owner_name": nickname_dict.get(group.creator_name, ''),
                "created_at": isoformat_timestr,
                "parent_group_id":
                group.parent_group_id if is_pro_version() else 0
            }
            groups_info.append(group_info)

            try:
                is_group_staff = ccnet_api.check_group_staff(group.id, email)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

            if email == group.creator_name:
                group_info['role'] = 'Owner'
            elif is_group_staff:
                group_info['role'] = 'Admin'
            else:
                group_info['role'] = 'Member'
        return Response({'group_list': groups_info})
Beispiel #24
0
def check_file_lock(repo_id, file_path, username):
    """ Check if file is locked to current user

    According to returned value of seafile_api.check_file_lock:
    0: not locked
    1: locked by other
    2: locked by me
    -1: error

    Return (is_locked, locked_by_me)
    """

    if not is_pro_version() or not ENABLE_FOLDER_PERM:
        return (False, False)

    return_value = seafile_api.check_file_lock(repo_id,
            file_path.lstrip('/'), username)

    if return_value == 0:
        return (False, False)
    elif return_value == 1:
        return (True , False)
    elif return_value == 2:
        return (True, True)
    else:
        raise SearpcError('check file lock error')
Beispiel #25
0
def edit_profile(request):
    """
    Show and edit user profile.
    """
    username = request.user.username
    form_class = DetailedProfileForm

    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            form.save(username=username)
            messages.success(request, _(u'Successfully edited profile.'))

            return HttpResponseRedirect(reverse('edit_profile'))
        else:
            messages.error(request, _(u'Failed to edit profile'))
    else:
        profile = Profile.objects.get_profile_by_user(username)
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
            username)

        init_dict = {}
        if profile:
            init_dict['nickname'] = profile.nickname
            init_dict['login_id'] = profile.login_id
            init_dict['contact_email'] = profile.contact_email
        if d_profile:
            init_dict['department'] = d_profile.department
            init_dict['telephone'] = d_profile.telephone
        form = form_class(init_dict)

    # common logic
    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)

    default_repo_id = UserOptions.objects.get_default_repo(username)
    if default_repo_id:
        default_repo = seafile_api.get_repo(default_repo_id)
    else:
        default_repo = None

    owned_repos = get_owned_repo_list(request)
    owned_repos = filter(lambda r: not r.is_virtual, owned_repos)

    return render_to_response('profile/set_profile.html', {
            'form': form,
            'server_crypto': server_crypto,
            "sub_lib_enabled": sub_lib_enabled,
            'force_server_crypto': settings.FORCE_SERVER_CRYPTO,
            'default_repo': default_repo,
            'owned_repos': owned_repos,
            'is_pro': is_pro_version(),
            'is_ldap_user': is_ldap_user(request.user),
            'two_factor_auth_enabled': has_two_factor_auth(),
            }, context_instance=RequestContext(request))
Beispiel #26
0
    def get(self, request):

        if not is_pro_version():
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # check the date format, should be like '2015-10-10'
        start = request.GET.get('start', None)
        end = request.GET.get('end', None)

        if not check_time_period_valid(start, end):
            error_msg = 'start or end date invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # Filtering a DateTimeField with dates won't include items on the last day,
        # because the bounds are interpreted as '0am on the given date'.
        end = end + ' 23:59:59'

        result = []
        from seahub_extra.sysadmin_extra.models import UserLoginLog
        logs = UserLoginLog.objects.filter(login_date__range=(start, end))
        for log in logs:
            result.append({
                'login_time':
                datetime_to_isoformat_timestr(log.login_date),
                'login_ip':
                log.login_ip,
                'name':
                email2nickname(log.username),
                'email':
                log.username
            })

        return Response(result)
Beispiel #27
0
def user_toggle_role(request, email):
    content_type = 'application/json; charset=utf-8'

    if not is_valid_username(email):
        return HttpResponse(json.dumps({'success': False}),
                            status=400,
                            content_type=content_type)

    if not is_pro_version():
        return HttpResponse(json.dumps({'success': False}),
                            status=403,
                            content_type=content_type)

    try:
        user_role = request.POST.get('r', DEFAULT_USER)
    except ValueError:
        user_role = DEFAULT_USER

    try:
        user = User.objects.get(email)
        User.objects.update_role(user.email, user_role)

        return HttpResponse(json.dumps({'success': True}),
                            content_type=content_type)
    except User.DoesNotExist:
        return HttpResponse(json.dumps({'success': False}),
                            status=500,
                            content_type=content_type)
Beispiel #28
0
    def _decorated(view, request, *args, **kwargs):
        if not is_pro_version() or not EVENTS_ENABLED:
            return api_error(status.HTTP_404_NOT_FOUND, 'Events not enabled.')
        start_time = request.GET.get("start", "")
        end_time = request.GET.get("end", "")
        if not start_time:
            error_msg = "Start time can not be empty"
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        if not end_time:
            error_msg = "End time can not be empty"
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        try:
            start_time = datetime.datetime.strptime(start_time,
                                                    "%Y-%m-%d %H:%M:%S")
        except:
            error_msg = "Start time %s invalid" % start_time
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
        try:
            end_time = datetime.datetime.strptime(end_time,
                                                  "%Y-%m-%d %H:%M:%S")
        except:
            error_msg = "End time %s invalid" % end_time
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        return func(view, request, start_time, end_time, *args, **kwargs)
Beispiel #29
0
    def authenticate(self, username, password):
        if not is_pro_version() or not ENABLE_LDAP:
            return

        self.l = ldap.initialize(LDAP_SERVER_URL)

        try:
            self.l.protocol_version = ldap.VERSION3
            self.l.simple_bind_s(LDAP_ADMIN_EMAIL, LDAP_ADMIN_PASSWORD)
        except ldap.INVALID_CREDENTIALS:
            logger.error('LDAP SETTINGS ERROR.')

        if LDAP_LOGIN_ATTR.lower() in ['email', 'mail']:
            filterstr = ldap.filter.filter_format(
                '(&(objectClass=user)(mail=%s))', [username])
        else:
            logger.error('LDAP SETTINGS ERROR.')
            return

        try:
            ldap_result_id = self.l.search(LDAP_BASE_DN, ldap.SCOPE_SUBTREE,
                                           filterstr)
            result_type, result_data = self.l.result(ldap_result_id, 1)
        except Exception as e:
            return

        # user not found in ldap
        if not result_data:
            return

        # delete old ldap connection instance and create new, if not, some err will occur
        self.l.unbind_s()
        del self.l
        self.l = ldap.initialize(LDAP_SERVER_URL)

        try:
            user_pricinpal_name, display_name = parse_userPrincipalName_and_displayName(
                result_data)
        except Exception:
            return

        try:
            self.l.protocol_version = ldap.VERSION3
            self.l.simple_bind_s(user_pricinpal_name, password)
        except ldap.INVALID_CREDENTIALS as e:
            return
        self.l.unbind_s()

        # check if existed
        user = self.get_user(username)
        if user:
            return user

        # user not in dtable, create user
        user = User.objects.create_ldap_user(email=username,
                                             nickname=display_name,
                                             is_active=True)
        return user
Beispiel #30
0
    def post(self, request):

        if not request.user.admin_permissions.can_config_system():
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        license_file = request.FILES.get('license', None)
        if not license_file:
            error_msg = 'license can not be found.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        file_type, ext = get_file_type_and_ext(license_file.name)
        if ext != 'txt':
            error_msg = file_type_error_msg(ext, 'txt')
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if license_file.size > 1024 * 1024 * 5:  # 5mb
            error_msg = file_size_error_msg(license_file.size, 5 * 1024 * 1024)
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        license_dir = os.path.dirname(LICENSE_PATH)
        try:
            if not os.path.exists(license_dir):
                error_msg = 'path %s invalid.' % LICENSE_PATH
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            with open(LICENSE_PATH, 'wb') as fd:
                fd.write(license_file.read())

            ccnet_api.reload_license()
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # get license info
        is_pro = is_pro_version()
        if is_pro:
            license_dict = parse_license()
        else:
            license_dict = {}

        if license_dict:
            try:
                max_users = int(license_dict.get('MaxUsers', 3))
            except ValueError as e:
                logger.error(e)
                max_users = 0
        else:
            max_users = 0

        license_info = {
            'license_expiration': license_dict.get('Expiration', ''),
            'license_mode': license_dict.get('Mode', ''),
            'license_maxusers': max_users,
            'license_to': license_dict.get('Name', ''),
        }

        return Response(license_info, status=status.HTTP_200_OK)
Beispiel #31
0
def if_locked_by_online_office(repo_id, path):

    locked_by_online_office = False
    if is_pro_version():
        lock_info = seafile_api.get_lock_info(repo_id, path)
        if lock_info and lock_info.user == ONLINE_OFFICE_LOCK_OWNER:
            locked_by_online_office = True

    return locked_by_online_office
Beispiel #32
0
def if_locked_by_online_office(repo_id, path):

    locked_by_online_office = False
    if is_pro_version():
        lock_info = seafile_api.get_lock_info(repo_id, path)
        if lock_info and lock_info.user == ONLINE_OFFICE_LOCK_OWNER:
            locked_by_online_office = True

    return locked_by_online_office
Beispiel #33
0
    def put(self, request, repo_id, format=None):
        """ Currently only for lock and unlock file operation.

        Permission checking:
        1. user with 'rw' permission for current file;
        """

        if not is_pro_version():
            error_msg = 'file lock feature only supported in professional edition.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # argument check
        path = request.GET.get('p', None)
        if not path:
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        operation = request.data.get('operation', None)
        if not operation:
            error_msg = 'operation invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        operation = operation.lower()
        if operation not in ('lock', 'unlock'):
            error_msg = "operation can only be 'lock', or 'unlock'."
            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)

        file_id = seafile_api.get_file_id_by_path(repo_id, path)
        if not file_id:
            error_msg = 'File %s not found.' % path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        parent_dir = os.path.dirname(path)
        if check_folder_permission(request, repo_id, parent_dir) != 'rw':
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        username = request.user.username
        is_locked, locked_by_me = check_file_lock(repo_id, path, username)
        if operation == 'lock':
            if not is_locked:
                # lock file
                expire = request.data.get('expire', FILE_LOCK_EXPIRATION_DAYS)
                try:
                    seafile_api.lock_file(repo_id, path.lstrip('/'), username, expire)
                except SearpcError, e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
Beispiel #34
0
def update_user_info(request):

    email = request.data.get("email")
    user = User.objects.get(email=email)

    # update basic user info
    password = request.data.get("password")
    if password:
        user.set_password(password)

    is_staff = request.data.get("is_staff")
    if is_staff:
        is_staff = to_python_boolean(is_staff)
        user.is_staff = is_staff

    is_active = request.data.get("is_active")
    if is_active:
        is_active = to_python_boolean(is_active)
        user.is_active = is_active

    # update user
    user.save()

    # update additional user info
    if is_pro_version():
        role = request.data.get("role")
        if role:
            User.objects.update_role(email, role)

    name = request.data.get("name")
    if name:
        profile = Profile.objects.get_profile_by_user(email)
        if profile is None:
            profile = Profile(user=email)
        profile.nickname = name
        profile.save()

    department = request.data.get("department")
    if department:
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email)
        if d_profile is None:
            d_profile = DetailedProfile(user=email)

        d_profile.department = department
        d_profile.save()

    quota_total_mb = request.data.get("quota_total")
    if quota_total_mb:
        quota_total = int(quota_total_mb) * get_file_size_unit('MB')
        if is_org_context(request):
            org_id = request.user.org.org_id
            seafile_api.set_org_user_quota(org_id, email, quota_total)
        else:
            seafile_api.set_user_quota(email, quota_total)
Beispiel #35
0
def unlock_file(request):

    key, value = generate_file_lock_key_value(request)
    cache.delete(key)

    if is_pro_version():
        token = request.GET.get('access_token', None)
        info_dict = get_file_info_by_token(token)
        repo_id = info_dict['repo_id']
        file_path = info_dict['file_path']
        seafile_api.unlock_file(repo_id, file_path)
Beispiel #36
0
def can_view_sys_admin_repo(repo):
    default_repo_id = get_system_default_repo_id()
    is_default_repo = True if repo.id == default_repo_id else False

    if is_default_repo:
        return True
    elif repo.encrypted:
        return False
    elif is_pro_version() and ENABLE_SYS_ADMIN_VIEW_REPO:
        return True
    else:
        return False
Beispiel #37
0
    def delete(self, request, format=None):
        if not is_pro_version():
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        try:
            seafile_api.clear_repo_sync_errors()
        except SearpcError 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})
Beispiel #38
0
def libraries(request):
    """
    New URL to replace myhome
    """
    username = request.user.username

    # options
    if request.cloud_mode and request.user.org is None:
        allow_public_share = False
    else:
        allow_public_share = True
    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)
    max_upload_file_size = get_max_upload_file_size()
    guide_enabled = UserOptions.objects.is_user_guide_enabled(username)
    if guide_enabled:
        create_default_library(request)

    folder_perm_enabled = True if is_pro_version() and ENABLE_FOLDER_PERM else False
    can_add_pub_repo = True if is_org_repo_creation_allowed(request) else False

    return render_to_response('libraries.html', {
            "allow_public_share": allow_public_share,
            "guide_enabled": guide_enabled,
            "sub_lib_enabled": sub_lib_enabled,
            'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
            'enable_resumable_fileupload': settings.ENABLE_RESUMABLE_FILEUPLOAD,
            'enable_thumbnail': settings.ENABLE_THUMBNAIL,
            'thumbnail_default_size': settings.THUMBNAIL_DEFAULT_SIZE,
            'thumbnail_size_for_grid': settings.THUMBNAIL_SIZE_FOR_GRID,
            'enable_encrypted_library': config.ENABLE_ENCRYPTED_LIBRARY,
            'enable_repo_history_setting': config.ENABLE_REPO_HISTORY_SETTING,
            'max_upload_file_size': max_upload_file_size,
            'folder_perm_enabled': folder_perm_enabled,
            'is_pro': True if is_pro_version() else False,
            'file_audit_enabled': FILE_AUDIT_ENABLED,
            'can_add_pub_repo': can_add_pub_repo,
            }, context_instance=RequestContext(request))
Beispiel #39
0
    def is_sub_lib_enabled(self, username):
        """Return ``True`` if is not pro version AND sub lib enabled, otherwise ``False``.
        
        Arguments:
        - `self`:
        - `username`:
        """
        if is_pro_version():
            return False

        try:
            user_option = super(UserOptionsManager, self).get(email=username, option_key=KEY_SUB_LIB)
            return bool(int(user_option.option_val))
        except UserOptions.DoesNotExist:
            return False
Beispiel #40
0
    def _decorated(request, token, *args, **kwargs):
        assert token is not None    # Checked by URLconf

        fileshare = FileShare.objects.get_valid_file_link_by_token(token) or \
                    FileShare.objects.get_valid_dir_link_by_token(token) or \
                    UploadLinkShare.objects.get_valid_upload_link_by_token(token)

        if fileshare is None:
            raise Http404

        if not is_pro_version() or not settings.ENABLE_SHARE_LINK_AUDIT:
            return func(request, fileshare, *args, **kwargs)

        # no audit for authenticated user, since we've already got email address
        if request.user.is_authenticated():
            return func(request, fileshare, *args, **kwargs)

        # anonymous user
        if request.session.get('anonymous_email') is not None:
            request.user.username = request.session.get('anonymous_email')
            return func(request, fileshare, *args, **kwargs)

        if request.method == 'GET':
            return render_to_response('share/share_link_audit.html', {
                'token': token,
            }, context_instance=RequestContext(request))
        elif request.method == 'POST':
            code = request.POST.get('code', '')
            email = request.POST.get('email', '')

            cache_key = normalize_cache_key(email, 'share_link_audit_')
            if code == cache.get(cache_key):
                # code is correct, add this email to session so that he will
                # not be asked again during this session, and clear this code.
                request.session['anonymous_email'] = email
                request.user.username = request.session.get('anonymous_email')
                cache.delete(cache_key)
                return func(request, fileshare, *args, **kwargs)
            else:
                return render_to_response('share/share_link_audit.html', {
                    'err_msg': 'Invalid token, please try again.',
                    'email': email,
                    'code': code,
                    'token': token,
                }, context_instance=RequestContext(request))
        else:
            assert False, 'TODO'
Beispiel #41
0
def sub_lib_enable_set(request):
    """
    """
    if is_pro_version():
        raise Http404

    username = request.user.username
    enable_sub_lib = request.POST.get('enable-sub-lib', '')

    if enable_sub_lib:
        UserOptions.objects.enable_sub_lib(username)
    else:
        UserOptions.objects.disable_sub_lib(username)

    next = request.META.get('HTTP_REFERER', None)
    if next is None:
        next = SITE_ROOT

    return HttpResponseRedirect(next)
Beispiel #42
0
    def get(self, request, format=None):
        if not is_pro_version():
            error_msg = 'Feature disabled.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        return_results = []
        try:
            device_errors = seafile_api.list_repo_sync_errors()
        except SearpcError as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        for error in device_errors:
            result = {}
            result['email'] = error.email if error.email else ''
            result['name'] = email2nickname(error.email)
            result['device_ip'] = error.peer_ip if error.peer_ip else ''
            result['repo_name'] = error.repo_name if error.repo_name else ''
            result['repo_id'] = error.repo_id if error.repo_id else ''
            result['error_msg'] = error.error_con if error.error_con else ''

            tokens = TokenV2.objects.filter(device_id = error.peer_id)
            if tokens:
                result['device_name'] = tokens[0].device_name
                result['client_version'] = tokens[0].client_version
            else:
                result['device_name'] = ''
                result['client_version'] = ''

            if error.error_time:
                result['error_time'] = timestamp_to_isoformat_timestr(error.error_time)
            else:
                result['error_time'] = ''

            return_results.append(result)

        return Response(return_results)
Beispiel #43
0
def sys_user_admin(request):
    """List all users from database.
    """
    # Make sure page request is an int. If not, deliver first page.
    try:
        current_page = int(request.GET.get('page', '1'))
        per_page = int(request.GET.get('per_page', '25'))
    except ValueError:
        current_page = 1
        per_page = 25
    users_plus_one = get_emailusers('DB', per_page * (current_page - 1), per_page + 1)
    if len(users_plus_one) == per_page + 1:
        page_next = True
    else:
        page_next = False

    users = users_plus_one[:per_page]
    last_logins = UserLastLogin.objects.filter(username__in=[x.email for x in users])
    if enable_trial_account:
        trial_users = TrialAccount.objects.filter(user_or_org__in=[x.email for x in users])
    else:
        trial_users = []
    for user in users:
        if user.props.id == request.user.id:
            user.is_self = True

        _populate_user_quota_usage(user)

        # check user's role
        if user.role == GUEST_USER:
            user.is_guest = True
        else:
            user.is_guest = False

        # populate user last login time
        user.last_login = None
        for last_login in last_logins:
            if last_login.username == user.email:
                user.last_login = last_login.last_login

        user.trial_info = None
        for trial_user in trial_users:
            if trial_user.user_or_org == user.email:
                user.trial_info = {'expire_date': trial_user.expire_date}

    have_ldap = True if len(get_emailusers('LDAP', 0, 1)) > 0 else False

    platform = get_platform_name()
    server_id = get_server_id()
    pro_server = 1 if is_pro_version() else 0

    return render_to_response(
        'sysadmin/sys_useradmin.html', {
            'users': users,
            'current_page': current_page,
            'prev_page': current_page-1,
            'next_page': current_page+1,
            'per_page': per_page,
            'page_next': page_next,
            'CALC_SHARE_USAGE': CALC_SHARE_USAGE,
            'have_ldap': have_ldap,
            'platform': platform,
            'server_id': server_id[:8],
            'default_user': DEFAULT_USER,
            'guest_user': GUEST_USER,
            'enable_guest': ENABLE_GUEST,
            'pro_server': pro_server,
        }, context_instance=RequestContext(request))
Beispiel #44
0
    def post(self, request, repo_id, format=None):
        repo = seafile_api.get_repo(repo_id)
        if not repo:
            return api_error(status.HTTP_404_NOT_FOUND, 'Library not found.')

        path = request.GET.get('p', '')
        if not path or path[0] != '/':
            error_msg = 'p invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if path == '/':
            error_msg = 'Can not make or rename root dir.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        if path[-1] == '/':
            path = path[:-1]

        username = request.user.username
        parent_dir = os.path.dirname(path)
        operation = request.POST.get('operation', '')
        if operation.lower() == 'mkdir':
            parent_dir = os.path.dirname(path)
            if check_folder_permission(request, repo_id, parent_dir) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            create_parents = request.POST.get('create_parents', '').lower() in ('true', '1')
            if not create_parents:
                parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
                if not parent_dir_id:
                    error_msg = 'Folder %s not found.' % parent_dir
                    return api_error(status.HTTP_404_NOT_FOUND, error_msg)

                new_dir_name = os.path.basename(path)
                new_dir_name = check_filename_with_rename(repo_id, parent_dir, new_dir_name)
                try:
                    seafile_api.post_dir(repo_id, parent_dir, new_dir_name, username)
                except SearpcError as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
            else:
                if not is_pro_version():
                    error_msg = 'Feature not supported.'
                    return api_error(status.HTTP_403_FORBIDDEN, error_msg)

                try:
                    seafile_api.mkdir_with_parents(repo_id, '/', path[1:], username)
                except SearpcError as e:
                    logger.error(e)
                    error_msg = 'Internal Server Error'
                    return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

            if request.GET.get('reloaddir', '').lower() == 'true':
                resp = reloaddir(request, repo, parent_dir)
            else:
                resp = Response({'success': True})

            return resp

        elif operation.lower() == 'rename':
            dir_id = seafile_api.get_dir_id_by_path(repo_id, path)
            if not dir_id:
                error_msg = 'Folder %s not found.' % path
                return api_error(status.HTTP_404_NOT_FOUND, error_msg)

            if check_folder_permission(request, repo.id, path) != 'rw':
                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

            parent_dir = os.path.dirname(path)
            old_dir_name = os.path.basename(path)
            newname = request.POST.get('newname', '')
            if not newname:
                error_msg = 'newname invalid.'
                return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

            if newname == old_dir_name:
                return Response({'success': True})

            try:
                # rename duplicate name
                checked_newname = check_filename_with_rename(repo_id, parent_dir, newname)
                # rename dir
                seafile_api.rename_file(repo_id, parent_dir, old_dir_name,
                                        checked_newname, username)
                return Response({'success': True})
            except SearpcError, e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
Beispiel #45
0
def update_user_info(request, user):

    # update basic user info
    password = request.data.get("password")
    if password:
        user.set_password(password)

    is_staff = request.data.get("is_staff")
    if is_staff:
        is_staff = to_python_boolean(is_staff)
        user.is_staff = is_staff

    is_active = request.data.get("is_active")
    if is_active:
        is_active = to_python_boolean(is_active)
        user.is_active = is_active

    # update user
    user.save()

    email = user.username

    # update additional user info
    if is_pro_version():
        role = request.data.get("role")
        if role:
            User.objects.update_role(email, role)

    nickname = request.data.get("name", None)
    if nickname is not None:
        Profile.objects.add_or_update(email, nickname)

    # update account login_id
    login_id = request.data.get("login_id", None)
    if login_id is not None:
        Profile.objects.add_or_update(email, login_id=login_id)

    # update account contact email
    contact_email = request.data.get('contact_email', None)
    if contact_email is not None:
        Profile.objects.add_or_update(email, contact_email=contact_email)
        key = normalize_cache_key(email, CONTACT_CACHE_PREFIX)
        cache.set(key, contact_email, CONTACT_CACHE_TIMEOUT)

    reference_id = request.data.get("reference_id", None)
    if reference_id is not None:
        if reference_id.strip():
            ccnet_api.set_reference_id(email, reference_id.strip())
        else:
            # remove reference id
            ccnet_api.set_reference_id(email, None)

    department = request.data.get("department")
    if department:
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(email)
        if d_profile is None:
            d_profile = DetailedProfile(user=email)

        d_profile.department = department
        d_profile.save()

    quota_total_mb = request.data.get("quota_total")
    if quota_total_mb:
        quota_total = int(quota_total_mb) * get_file_size_unit('MB')
        if is_org_context(request):
            org_id = request.user.org.org_id
            seafile_api.set_org_user_quota(org_id, email, quota_total)
        else:
            seafile_api.set_user_quota(email, quota_total)
Beispiel #46
0
def get_library_storages(request):
    """ Return info of storages can be used.

    1. If not enable user role feature OR
       haven't configured `storage_ids` option in user role setting:

       Return storage info getted from seafile_api.
       And always put the default storage as the first item in the returned list.

    2. If have configured `storage_ids` option in user role setting:

       Only return storage info in `storage_ids`.
       Filter out the wrong stotage id(s).
       Not change the order of the `storage_ids` list.
    """

    if not is_pro_version():
        return []

    if not ENABLE_STORAGE_CLASSES:
        return []

    # get all storages info
    try:
        storage_classes = seafile_api.get_all_storage_classes()
    except Exception as e:
        logger.error(e)
        return []

    all_storages = []
    for storage in storage_classes:
        storage_info = {
            'storage_id': storage.storage_id,
            'storage_name': storage.storage_name,
            'is_default': storage.is_default,
        }
        if storage.is_default:
            all_storages.insert(0, storage_info)
        else:
            all_storages.append(storage_info)

    if STORAGE_CLASS_MAPPING_POLICY == 'USER_SELECT':

        return all_storages

    elif STORAGE_CLASS_MAPPING_POLICY == 'ROLE_BASED':
        user_role_storage_ids = request.user.permissions.storage_ids()
        if not user_role_storage_ids:
            return []

        user_role_storages = []
        for user_role_storage_id in user_role_storage_ids:
            for storage in all_storages:
                if storage['storage_id'] == user_role_storage_id:
                    user_role_storages.append(storage)
                    continue

        return user_role_storages

    else:
        # STORAGE_CLASS_MAPPING_POLICY == 'REPO_ID_MAPPING'
        return []
Beispiel #47
0
    def get(self, request, format=None):
        """ Only used for download dir when view dir share link from web.


        Permission checking:
        1. authenticated user OR anonymous user has passed email code check(if necessary);
        """

        # permission check
        if is_pro_version() and settings.ENABLE_SHARE_LINK_AUDIT:
            if not request.user.is_authenticated() and \
                not request.session.get('anonymous_email'):
                # if anonymous user has passed email code check,
                # then his/her email info will be in session.

                error_msg = 'Permission denied.'
                return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # argument check
        share_link_token = request.GET.get('share_link_token', None)
        if not share_link_token:
            error_msg = 'share_link_token invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        req_path = request.GET.get('path', None)
        if not req_path:
            error_msg = 'path invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # recourse check
        fileshare = FileShare.objects.get_valid_dir_link_by_token(share_link_token)
        if not fileshare:
            error_msg = 'share_link_token %s not found.' % share_link_token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        if req_path[-1] != '/':
            req_path += '/'

        if req_path == '/':
            real_path = fileshare.path
        else:
            real_path = posixpath.join(fileshare.path, req_path.lstrip('/'))

        if real_path[-1] != '/':
            real_path += '/'

        repo_id = fileshare.repo_id
        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)

        dir_id = seafile_api.get_dir_id_by_path(repo_id, real_path)
        if not dir_id:
            error_msg = 'Folder %s not found.' % real_path
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # get file server access token
        dir_name = repo.name if real_path == '/' else \
                os.path.basename(real_path.rstrip('/'))

        dir_size = seafile_api.get_dir_size(
                repo.store_id, repo.version, dir_id)
        if dir_size > seaserv.MAX_DOWNLOAD_DIR_SIZE:
            error_msg = 'Unable to download directory "%s": size is too large.' % dir_name
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        is_windows = 0
        if is_windows_operating_system(request):
            is_windows = 1

        fake_obj_id = {
            'obj_id': dir_id,
            'dir_name': dir_name,
            'is_windows': is_windows
        }

        username = request.user.username
        try:
            zip_token = seafile_api.get_fileserver_access_token(
                    repo_id, json.dumps(fake_obj_id), 'download-dir', username)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        if request.session.get('anonymous_email'):
            request.user.username = request.session.get('anonymous_email')

        send_file_access_msg(request, repo, real_path, 'share-link')

        return Response({'zip_token': zip_token})
Beispiel #48
0
def get_dir_file_info_list(username, request_type, repo_obj, parent_dir,
        with_thumbnail, thumbnail_size):

    repo_id = repo_obj.id
    dir_info_list = []
    file_info_list = []

    # get dirent(folder and file) list
    parent_dir_id = seafile_api.get_dir_id_by_path(repo_id, parent_dir)
    dir_file_list = seafile_api.list_dir_with_perm(repo_id,
            parent_dir, parent_dir_id, username, -1, -1)

    try:
        starred_items = UserStarredFiles.objects.filter(email=username,
                repo_id=repo_id, path__startswith=parent_dir, org_id=-1)
        starred_item_path_list = [f.path.rstrip('/') for f in starred_items]
    except Exception as e:
        logger.error(e)
        starred_item_path_list = []

    # only get dir info list
    if not request_type or request_type == 'd':
        dir_list = [dirent for dirent in dir_file_list if stat.S_ISDIR(dirent.mode)]
        for dirent in dir_list:
            dir_info = {}
            dir_info["type"] = "dir"
            dir_info["id"] = dirent.obj_id
            dir_info["name"] = dirent.obj_name
            dir_info["mtime"] = dirent.mtime
            dir_info["permission"] = dirent.permission
            dir_info["parent_dir"] = parent_dir
            dir_info_list.append(dir_info)

            # get star info
            dir_info['starred'] = False
            dir_path = posixpath.join(parent_dir, dirent.obj_name)
            if dir_path.rstrip('/') in starred_item_path_list:
                dir_info['starred'] = True

    # only get file info list
    if not request_type or request_type == 'f':

        file_list = [dirent for dirent in dir_file_list if not stat.S_ISDIR(dirent.mode)]

        # Use dict to reduce memcache fetch cost in large for-loop.
        nickname_dict = {}
        contact_email_dict = {}
        modifier_set = set([x.modifier for x in file_list])
        lock_owner_set = set([x.lock_owner for x in file_list])
        for e in modifier_set | lock_owner_set:
            if e not in nickname_dict:
                nickname_dict[e] = email2nickname(e)
            if e not in contact_email_dict:
                contact_email_dict[e] = email2contact_email(e)

        try:
            files_tags_in_dir = get_files_tags_in_dir(repo_id, parent_dir)
        except Exception as e:
            logger.error(e)
            files_tags_in_dir = {}

        for dirent in file_list:

            file_name = dirent.obj_name
            file_path = posixpath.join(parent_dir, file_name)
            file_obj_id = dirent.obj_id

            file_info = {}
            file_info["type"] = "file"
            file_info["id"] = file_obj_id
            file_info["name"] = file_name
            file_info["mtime"] = dirent.mtime
            file_info["permission"] = dirent.permission
            file_info["parent_dir"] = parent_dir
            file_info["size"] = dirent.size

            modifier_email = dirent.modifier
            file_info['modifier_email'] = modifier_email
            file_info['modifier_name'] = nickname_dict.get(modifier_email, '')
            file_info['modifier_contact_email'] = contact_email_dict.get(modifier_email, '')

            # get lock info
            if is_pro_version():
                file_info["is_locked"] = dirent.is_locked
                file_info["lock_time"] = dirent.lock_time

                lock_owner_email = dirent.lock_owner or ''
                file_info["lock_owner"] = lock_owner_email
                file_info['lock_owner_name'] = nickname_dict.get(lock_owner_email, '')
                file_info['lock_owner_contact_email'] = contact_email_dict.get(lock_owner_email, '')

                if username == lock_owner_email:
                    file_info["locked_by_me"] = True
                else:
                    file_info["locked_by_me"] = False

            # get star info
            file_info['starred'] = False
            if file_path.rstrip('/') in starred_item_path_list:
                file_info['starred'] = True

            # get tag info
            file_tags = files_tags_in_dir.get(file_name, [])
            if file_tags:
                file_info['file_tags'] = []
                for file_tag in file_tags:
                    file_info['file_tags'].append(file_tag)

            # get thumbnail info
            if with_thumbnail and not repo_obj.encrypted:

                # used for providing a way to determine
                # if send a request to create thumbnail.

                fileExt = os.path.splitext(file_name)[1][1:].lower()
                file_type = FILEEXT_TYPE_MAP.get(fileExt)

                if file_type in (IMAGE, XMIND) or \
                        file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL:

                    # if thumbnail has already been created, return its src.
                    # Then web browser will use this src to get thumbnail instead of
                    # recreating it.
                    thumbnail_file_path = os.path.join(THUMBNAIL_ROOT,
                            str(thumbnail_size), file_obj_id)
                    if os.path.exists(thumbnail_file_path):
                        src = get_thumbnail_src(repo_id, thumbnail_size, file_path)
                        file_info['encoded_thumbnail_src'] = urlquote(src)

            file_info_list.append(file_info)

    dir_info_list.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))
    file_info_list.sort(lambda x, y: cmp(x['name'].lower(), y['name'].lower()))

    return dir_info_list, file_info_list
Beispiel #49
0
    def get(self, request):
        """ Return repos user can access.

        Permission checking:
        1. all authenticated user can perform this action.
        """

        filter_by = {
            'mine': False,
            'shared': False,
            'group': False,
            'public': False,
        }

        request_type_list = request.GET.getlist('type', "")
        if not request_type_list:
            # set all to True, no filter applied
            filter_by = filter_by.fromkeys(filter_by.iterkeys(), True)

        for request_type in request_type_list:
            request_type = request_type.strip()
            filter_by[request_type] = True

        email = request.user.username

        # Use dict to reduce memcache fetch cost in large for-loop.
        contact_email_dict = {}
        nickname_dict = {}

        org_id = None
        if is_org_context(request):
            org_id = request.user.org.org_id

        try:
            starred_repos = UserStarredFiles.objects.get_starred_repos_by_user(email)
            starred_repo_id_list = [item.repo_id for item in starred_repos]
        except Exception as e:
            logger.error(e)
            starred_repo_id_list = []

        repo_info_list = []
        if filter_by['mine']:

            if org_id:
                owned_repos = seafile_api.get_org_owned_repo_list(org_id,
                        email, ret_corrupted=True)
            else:
                owned_repos = seafile_api.get_owned_repo_list(email,
                        ret_corrupted=True)

            # Reduce memcache fetch ops.
            modifiers_set = set([x.last_modifier for x in owned_repos])
            for e in modifiers_set:
                if e not in contact_email_dict:
                    contact_email_dict[e] = email2contact_email(e)
                if e not in nickname_dict:
                    nickname_dict[e] = email2nickname(e)

            owned_repos.sort(lambda x, y: cmp(y.last_modify, x.last_modify))
            for r in owned_repos:

                # do not return virtual repos
                if r.is_virtual:
                    continue

                repo_info = {
                    "type": "mine",
                    "repo_id": r.id,
                    "repo_name": r.name,
                    "owner_email": email,
                    "owner_name": email2nickname(email),
                    "owner_contact_email": email2contact_email(email),
                    "last_modified": timestamp_to_isoformat_timestr(r.last_modify),
                    "modifier_email": r.last_modifier,
                    "modifier_name": nickname_dict.get(r.last_modifier, ''),
                    "modifier_contact_email": contact_email_dict.get(r.last_modifier, ''),
                    "size": r.size,
                    "encrypted": r.encrypted,
                    "permission": 'rw',  # Always have read-write permission to owned repo
                    "starred": r.repo_id in starred_repo_id_list,
                }

                if is_pro_version() and ENABLE_STORAGE_CLASSES:
                    repo_info['storage_name'] = r.storage_name
                    repo_info['storage_id'] = r.storage_id

                repo_info_list.append(repo_info)

        if filter_by['shared']:

            if org_id:
                shared_repos = seafile_api.get_org_share_in_repo_list(org_id,
                        email, -1, -1)
            else:
                shared_repos = seafile_api.get_share_in_repo_list(
                        email, -1, -1)

            repos_with_admin_share_to = ExtraSharePermission.objects.\
                    get_repos_with_admin_permission(email)

            # Reduce memcache fetch ops.
            owners_set = set([x.user for x in shared_repos])
            modifiers_set = set([x.last_modifier for x in shared_repos])
            for e in owners_set | modifiers_set:
                if e not in contact_email_dict:
                    contact_email_dict[e] = email2contact_email(e)
                if e not in nickname_dict:
                    nickname_dict[e] = email2nickname(e)

            shared_repos.sort(lambda x, y: cmp(y.last_modify, x.last_modify))
            for r in shared_repos:

                owner_email = r.user

                group_name = ''
                is_group_owned_repo = False
                if '@seafile_group' in owner_email:
                    is_group_owned_repo = True
                    group_id = get_group_id_by_repo_owner(owner_email)
                    group_name= group_id_to_name(group_id)

                owner_name = group_name if is_group_owned_repo else \
                        nickname_dict.get(owner_email, '')
                owner_contact_email = '' if is_group_owned_repo else \
                        contact_email_dict.get(owner_email, '')

                repo_info = {
                    "type": "shared",
                    "repo_id": r.repo_id,
                    "repo_name": r.repo_name,
                    "last_modified": timestamp_to_isoformat_timestr(r.last_modify),
                    "modifier_email": r.last_modifier,
                    "modifier_name": nickname_dict.get(r.last_modifier, ''),
                    "modifier_contact_email": contact_email_dict.get(r.last_modifier, ''),
                    "owner_email": owner_email,
                    "owner_name": owner_name,
                    "owner_contact_email": owner_contact_email,
                    "size": r.size,
                    "encrypted": r.encrypted,
                    "permission": r.permission,
                    "starred": r.repo_id in starred_repo_id_list,
                }

                if r.repo_id in repos_with_admin_share_to:
                    repo_info['is_admin'] = True
                else:
                    repo_info['is_admin'] = False

                repo_info_list.append(repo_info)

        if filter_by['group']:

            if org_id:
                group_repos = seafile_api.get_org_group_repos_by_user(email, org_id)
            else:
                group_repos = seafile_api.get_group_repos_by_user(email)

            group_repos.sort(lambda x, y: cmp(y.last_modify, x.last_modify))

            # Reduce memcache fetch ops.
            share_from_set = set([x.user for x in group_repos])
            modifiers_set = set([x.last_modifier for x in group_repos])
            for e in modifiers_set | share_from_set:
                if e not in contact_email_dict:
                    contact_email_dict[e] = email2contact_email(e)
                if e not in nickname_dict:
                    nickname_dict[e] = email2nickname(e)

            for r in group_repos:
                repo_info = {
                    "type": "group",
                    "group_id": r.group_id,
                    "group_name": r.group_name,
                    "repo_id": r.repo_id,
                    "repo_name": r.repo_name,
                    "last_modified": timestamp_to_isoformat_timestr(r.last_modify),
                    "modifier_email": r.last_modifier,
                    "modifier_name": nickname_dict.get(r.last_modifier, ''),
                    "modifier_contact_email": contact_email_dict.get(r.last_modifier, ''),
                    "size": r.size,
                    "encrypted": r.encrypted,
                    "permission": r.permission,
                    "starred": r.repo_id in starred_repo_id_list,
                }
                repo_info_list.append(repo_info)

        if filter_by['public'] and request.user.permissions.can_view_org():
            public_repos = list_inner_pub_repos(request)

            # get repo id owner dict
            all_repo_owner = []
            repo_id_owner_dict = {}
            for repo in public_repos:
                repo_id = repo.repo_id
                if repo_id not in repo_id_owner_dict:
                    repo_owner = get_repo_owner(request, repo_id)
                    all_repo_owner.append(repo_owner)
                    repo_id_owner_dict[repo_id] = repo_owner

            # Reduce memcache fetch ops.
            owner_set = set(all_repo_owner)
            share_from_set = set([x.user for x in public_repos])
            modifiers_set = set([x.last_modifier for x in public_repos])
            for e in modifiers_set | share_from_set | owner_set:
                if e not in contact_email_dict:
                    contact_email_dict[e] = email2contact_email(e)
                if e not in nickname_dict:
                    nickname_dict[e] = email2nickname(e)

            for r in public_repos:
                repo_owner = repo_id_owner_dict[r.repo_id]
                repo_info = {
                    "type": "public",
                    "repo_id": r.repo_id,
                    "repo_name": r.repo_name,
                    "last_modified": timestamp_to_isoformat_timestr(r.last_modify),
                    "modifier_email": r.last_modifier,
                    "modifier_name": nickname_dict.get(r.last_modifier, ''),
                    "modifier_contact_email": contact_email_dict.get(r.last_modifier, ''),
                    "owner_email": repo_owner,
                    "owner_name": nickname_dict.get(repo_owner, ''),
                    "owner_contact_email": contact_email_dict.get(repo_owner, ''),
                    "size": r.size,
                    "encrypted": r.encrypted,
                    "permission": r.permission,
                    "starred": r.repo_id in starred_repo_id_list,
                }
                repo_info_list.append(repo_info)

        utc_dt = datetime.datetime.utcnow()
        timestamp = utc_dt.strftime('%Y-%m-%d %H:%M:%S')
        org_id = request.user.org.org_id if is_org_context(request) else -1
        try:
            send_message('seahub.stats', 'user-login\t%s\t%s\t%s' % (email, timestamp, org_id))
        except Exception as e:
            logger.error('Error when sending user-login message: %s' % str(e))

        return Response({'repos': repo_info_list})
Beispiel #50
0
    def get(self, request, format=None):
        # count repos
        try:
            repos_count = seafile_api.count_repos()
        except SearpcError as e:
            logger.error(e)
            repos_count = 0

        # count groups
        try:
            groups_count = len(ccnet_api.get_all_groups(-1, -1))
        except Exception as e:
            logger.error(e)
            groups_count = 0

        # count orgs
        if MULTI_TENANCY:
            multi_tenancy_enabled = True
            try:
                org_count = ccnet_api.count_orgs()
            except Exception as e:
                logger.error(e)
                org_count = 0
        else:
            multi_tenancy_enabled = False
            org_count = 0

        # count users
        try:
            active_db_users = ccnet_api.count_emailusers('DB')
        except Exception as e:
            logger.error(e)
            active_db_users = 0

        try:
            active_ldap_users = ccnet_api.count_emailusers('LDAP')
        except Exception as e:
            logger.error(e)
            active_ldap_users = 0

        try:
            inactive_db_users = ccnet_api.count_inactive_emailusers('DB')
        except Exception as e:
            logger.error(e)
            inactive_db_users = 0

        try:
            inactive_ldap_users = ccnet_api.count_inactive_emailusers('LDAP')
        except Exception as e:
            logger.error(e)
            inactive_ldap_users = 0

        active_users = active_db_users + active_ldap_users if \
            active_ldap_users > 0 else active_db_users

        inactive_users = inactive_db_users + inactive_ldap_users if \
            inactive_ldap_users > 0 else inactive_db_users

        # get license info
        is_pro = is_pro_version()
        if is_pro:
            license_dict = parse_license()
        else:
            license_dict = {}

        if license_dict:
            with_license = True
            try:
                max_users = int(license_dict.get('MaxUsers', 3))
            except ValueError as e:
                logger.error(e)
                max_users = 0
        else:
            with_license = False
            max_users = 0

        # count total file number
        try:
            total_files_count = seafile_api.get_total_file_number()
        except Exception as e:
            logger.error(e)
            total_files_count = 0

        # count total storage
        try:
            total_storage = seafile_api.get_total_storage()
        except Exception as e:
            logger.error(e)
            total_storage = 0

        # count devices number
        try:
            total_devices_count = TokenV2.objects.get_total_devices_count()
        except Exception as e:
            logger.error(e)
            total_devices_count = 0

        # count current connected devices
        try:
            current_connected_devices_count = TokenV2.objects.\
                    get_current_connected_devices_count()
        except Exception as e:
            logger.error(e)
            current_connected_devices_count = 0

        info = {
            'users_count': active_users + inactive_users,
            'active_users_count': active_users,
            'repos_count': repos_count,
            'total_files_count': total_files_count,
            'groups_count': groups_count,
            'org_count': org_count,
            'multi_tenancy_enabled': multi_tenancy_enabled,
            'is_pro': is_pro,
            'with_license': with_license,
            'license_expiration': license_dict.get('Expiration', ''),
            'license_mode': license_dict.get('Mode', ''),
            'license_maxusers': max_users,
            'license_to': license_dict.get('Name', ''),
            'total_storage': total_storage,
            'total_devices_count': total_devices_count,
            'current_connected_devices_count': current_connected_devices_count
        }

        return Response(info)
Beispiel #51
0
def edit_profile(request):
    """
    Show and edit user profile.
    """
    username = request.user.username
    form_class = DetailedProfileForm

    if request.method == "POST":
        form = form_class(request.POST)
        if form.is_valid():
            form.save(username=username)
            messages.success(request, _(u"Successfully edited profile."))
            # refresh nickname cache
            refresh_cache(request.user.username)

            return HttpResponseRedirect(reverse("edit_profile"))
        else:
            messages.error(request, _(u"Failed to edit profile"))
    else:
        profile = Profile.objects.get_profile_by_user(username)
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(username)

        init_dict = {}
        if profile:
            init_dict["nickname"] = profile.nickname
            init_dict["intro"] = profile.intro
        if d_profile:
            init_dict["department"] = d_profile.department
            init_dict["telephone"] = d_profile.telephone
        form = form_class(init_dict)

    # common logic
    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)

    default_repo_id = UserOptions.objects.get_default_repo(username)
    if default_repo_id:
        default_repo = seafile_api.get_repo(default_repo_id)
    else:
        default_repo = None

    owned_repos = get_owned_repo_list(request)

    return render_to_response(
        "profile/set_profile.html",
        {
            "form": form,
            "server_crypto": server_crypto,
            "sub_lib_enabled": sub_lib_enabled,
            "force_server_crypto": settings.FORCE_SERVER_CRYPTO,
            "default_repo": default_repo,
            "owned_repos": owned_repos,
            "is_pro": is_pro_version(),
        },
        context_instance=RequestContext(request),
    )
Beispiel #52
0
def edit_profile(request):
    """
    Show and edit user profile.
    """
    username = request.user.username
    form_class = DetailedProfileForm

    if request.method == 'POST':
        form = form_class(user=request.user, data=request.POST)
        if form.is_valid():
            form.save()
            messages.success(request, _(u'Successfully edited profile.'))

            return HttpResponseRedirect(reverse('edit_profile'))
        else:
            messages.error(request, _(u'Failed to edit profile'))
    else:
        profile = Profile.objects.get_profile_by_user(username)
        d_profile = DetailedProfile.objects.get_detailed_profile_by_user(
            username)

        init_dict = {}
        if profile:
            init_dict['nickname'] = profile.nickname
            init_dict['login_id'] = profile.login_id
            init_dict['contact_email'] = profile.contact_email
            init_dict['list_in_address_book'] = profile.list_in_address_book
        if d_profile:
            init_dict['department'] = d_profile.department
            init_dict['telephone'] = d_profile.telephone

        form = form_class(user=request.user, data=init_dict)

    # common logic
    try:
        server_crypto = UserOptions.objects.is_server_crypto(username)
    except CryptoOptionNotSetError:
        # Assume server_crypto is ``False`` if this option is not set.
        server_crypto = False

    sub_lib_enabled = UserOptions.objects.is_sub_lib_enabled(username)

    default_repo_id = UserOptions.objects.get_default_repo(username)
    if default_repo_id:
        default_repo = seafile_api.get_repo(default_repo_id)
    else:
        default_repo = None

    owned_repos = get_owned_repo_list(request)
    owned_repos = filter(lambda r: not r.is_virtual, owned_repos)

    if settings.ENABLE_WEBDAV_SECRET:
        decoded = UserOptions.objects.get_webdav_decoded_secret(username)
        webdav_passwd = decoded if decoded else ''
    else:
        webdav_passwd = ''

    email_inverval = UserOptions.objects.get_file_updates_email_interval(username)
    email_inverval = email_inverval if email_inverval is not None else 0

    if settings.SOCIAL_AUTH_WEIXIN_WORK_KEY:
        enable_wechat_work = True

        from social_django.models import UserSocialAuth
        social_connected = UserSocialAuth.objects.filter(
            username=request.user.username, provider='weixin-work').count() > 0
    else:
        enable_wechat_work = False
        social_connected = False

    resp_dict = {
            'form': form,
            'server_crypto': server_crypto,
            "sub_lib_enabled": sub_lib_enabled,
            'ENABLE_ADDRESSBOOK_OPT_IN': settings.ENABLE_ADDRESSBOOK_OPT_IN,
            'default_repo': default_repo,
            'owned_repos': owned_repos,
            'is_pro': is_pro_version(),
            'is_ldap_user': is_ldap_user(request.user),
            'two_factor_auth_enabled': has_two_factor_auth(),
            'ENABLE_CHANGE_PASSWORD': settings.ENABLE_CHANGE_PASSWORD,
            'ENABLE_WEBDAV_SECRET': settings.ENABLE_WEBDAV_SECRET,
            'ENABLE_DELETE_ACCOUNT': ENABLE_DELETE_ACCOUNT,
            'ENABLE_UPDATE_USER_INFO': ENABLE_UPDATE_USER_INFO,
            'webdav_passwd': webdav_passwd,
            'email_notification_interval': email_inverval,
            'social_connected': social_connected,
            'social_next_page': reverse('edit_profile'),
            'enable_wechat_work': enable_wechat_work,
            'ENABLE_USER_SET_CONTACT_EMAIL': settings.ENABLE_USER_SET_CONTACT_EMAIL,
            'user_unusable_password': request.user.enc_password == UNUSABLE_PASSWORD,
    }

    if has_two_factor_auth():
        from seahub.two_factor.models import StaticDevice, default_device

        try:
            backup_tokens = StaticDevice.objects.get(
                user=request.user.username).token_set.count()
        except StaticDevice.DoesNotExist:
            backup_tokens = 0

        resp_dict['default_device'] = default_device(request.user)
        resp_dict['backup_tokens'] = backup_tokens

    #template = 'profile/set_profile.html'
    template = 'profile/set_profile_react.html'
    return render(request, template, resp_dict)
Beispiel #53
0
def get_available_repo_perms():
    perms = [PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN]
    if is_pro_version():
        perms += [PERMISSION_PREVIEW, PERMISSION_PREVIEW_EDIT]

    return perms
Beispiel #54
0
 def has_permission(self, request, *args, **kwargs):
     return is_pro_version()