コード例 #1
0
    def get(self, request, token):
        # resource check
        form_obj = DTableForms.objects.get_form_by_token(token)
        if not form_obj:
            error_msg = 'Form %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        workspace_id = form_obj.workspace_id
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        repo_id = workspace.repo_id

        dtable_uuid = form_obj.dtable_uuid
        dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
        if not dtable:
            error_msg = 'Table %s not found.' % dtable_uuid
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        if not check_form_submit_permission(request, form_obj):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        if not check_user_workspace_quota(workspace):
            error_msg = 'Asset quota exceeded.'
            return api_error(HTTP_443_ABOVE_QUOTA, error_msg)

        # create asset dir
        asset_dir_path = '/asset/' + str(dtable.uuid)
        asset_dir_id = seafile_api.get_dir_id_by_path(repo_id, asset_dir_path)
        if not asset_dir_id:
            seafile_api.mkdir_with_parents(repo_id, '/', asset_dir_path[1:],
                                           '')

        # get token
        obj_id = json.dumps({'parent_dir': asset_dir_path})
        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            obj_id,
                                                            'upload',
                                                            '',
                                                            use_onetime=False)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        upload_link = gen_file_upload_url(token, 'upload-api')

        res = dict()
        res['upload_link'] = upload_link
        res['parent_path'] = asset_dir_path
        res['img_relative_path'] = FORM_UPLOAD_IMG_RELATIVE_PATH
        res['file_relative_path'] = os.path.join(UPLOAD_FILE_RELATIVE_PATH,
                                                 str(datetime.today())[:7])
        return Response(res)
コード例 #2
0
    def get(self, request, workspace_id, name):
        """get dtable access token
        """

        table_name = name

        # resource check
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        dtable = DTables.objects.get_dtable(workspace, table_name)
        if not dtable:
            error_msg = 'dtable %s not found.' % table_name
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        username = request.user.username
        permission = check_dtable_permission(username, workspace, dtable)
        if not permission:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # generate json web token
        payload = {
            'exp':
            int(time.time()) + 86400 * 3,
            'dtable_uuid':
            dtable.uuid.hex,
            'username':
            username,
            'permission':
            permission
            if check_user_workspace_quota(dtable.workspace) else 'r',
        }

        try:
            access_token = jwt.encode(payload,
                                      DTABLE_PRIVATE_KEY,
                                      algorithm='HS256')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({
            'access_token': access_token,
            'dtable_uuid': dtable.uuid.hex,
            'dtable_server': DTABLE_SERVER_URL,
            'dtable_socket': DTABLE_SOCKET_URL,
        })
コード例 #3
0
    def get(self, request):
        """get dtable share link access token
        """

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

        # resource check
        dsl = DTableShareLinks.objects.filter(token=token).first()
        if not dsl:
            error_msg = 'Share link %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        workspace = Workspaces.objects.get_workspace_by_id(
            dsl.dtable.workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % dsl.workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        repo = seafile_api.get_repo(workspace.repo_id)
        if not repo:
            error_msg = 'Library %s not found.' % workspace.repo_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        dtable = DTables.objects.get_dtable_by_uuid(dsl.dtable.uuid)
        if not dtable:
            error_msg = 'DTable %s not found.' % dsl.dtable.uuid
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # generate jwt
        payload = {
            'exp':
            int(time.time()) + 86400 * 3,
            'dtable_uuid':
            dtable.uuid.hex,
            'username':
            dsl.username,
            'permission':
            dsl.permission
            if check_user_workspace_quota(dtable.workspace) else 'r',
        }

        try:
            access_token = jwt.encode(payload,
                                      DTABLE_PRIVATE_KEY,
                                      algorithm='HS256')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({
            'access_token': access_token,
            'dtable_uuid': dtable.uuid.hex,
        })
コード例 #4
0
ファイル: views.py プロジェクト: flazx/dtable-web
def dtable_file_view(request, workspace_id, name):
    """

    Permission:
    1. owner
    2. group member
    3. shared user
    """
    # resource check
    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        return render_error(request, 'Workspace does not exist.')

    group_id = ''
    if '@seafile_group' in workspace.owner:
        group_id = workspace.owner.split('@')[0]
        group = seaserv.get_group(group_id)
        if not group:
            error_msg = 'Group %s not found.' % group_id
            return render_error(request, error_msg)

    repo_id = workspace.repo_id
    repo = seafile_api.get_repo(repo_id)
    if not repo:
        return render_error(request, 'Library does not exist.')

    dtable = DTables.objects.get_dtable(workspace, name)
    if not dtable:
        return render_error(request, 'DTable does not exist.')

    # permission check
    username = request.user.username
    permission = check_dtable_permission(username, workspace, dtable)
    if not permission:
        return render_permission_error(request, _('Permission denied.'))

    is_admin = False
    if group_id:
        is_admin = is_group_admin_or_owner(group_id, username)
    else:
        # open your own dtable
        is_admin = username == workspace.owner

    seafile_url = ''
    repo_api_token = ''
    try:
        seafile_connector = SeafileConnectors.objects.get(dtable=dtable)
        seafile_url = seafile_connector.seafile_url
        repo_api_token = seafile_connector.repo_api_token
    except SeafileConnectors.DoesNotExist:
        pass

    return_dict = {
        'version':
        SEATABLE_VERSION,
        'dtable_baidu_map_key':
        DTABLE_BAIDU_MAP_KEY,
        'dtable_google_map_key':
        DTABLE_GOOGLE_MAP_KEY,
        'seatable_market_url':
        SEATABLE_MARKET_URL,
        'filename':
        name,
        'workspace_id':
        workspace_id,
        'dtable_uuid':
        dtable.uuid.hex,
        'permission':
        permission if check_user_workspace_quota(workspace) else 'r',
        'media_url':
        MEDIA_URL,
        'seafile_url':
        seafile_url,
        'repo_api_token':
        repo_api_token,
        'dtable_server':
        DTABLE_SERVER_URL,
        'dtable_socket':
        DTABLE_SOCKET_URL,
        'dtable_enable_geolocation_column':
        DTABLE_ENABLE_GEOLOCATION_COLUMN,
        'is_admin':
        is_admin,
        'asset_quota_exceeded':
        dtable.creator == request.user.username
        and not check_user_workspace_quota(workspace),
    }

    return render(request, 'dtable_file_view_react.html', return_dict)
コード例 #5
0
ファイル: views.py プロジェクト: flazx/dtable-web
def dtable_form_edit(request, token):
    """
    Permission:
    1. owner
    2. group member
    3. shared user with `rw` permission
    """

    # resource check
    form_obj = DTableForms.objects.get_form_by_token(token)
    if not form_obj:
        return render_error(request, 'Table\'s form does not exist.')

    workspace_id = form_obj.workspace_id
    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        return render_error(request, 'Workspace does not exist.')

    dtable_uuid = form_obj.dtable_uuid
    dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
    if not dtable:
        return render_error(request, 'Table does not exist.')

    # permission check
    username = request.user.username
    permission = check_dtable_permission(username, workspace, dtable)
    if permission != PERMISSION_READ_WRITE:
        return render_permission_error(request, 'Permission denied.')

    if not check_user_workspace_quota(workspace):
        return render_error(request, 'Asset quota exceeded.')

    # generate json web token
    payload = {
        'exp': int(time.time()) + 60 * 5,
        'dtable_uuid': dtable_uuid,
        'username': "******",
        'permission': permission,
    }

    try:
        access_token = jwt.encode(payload,
                                  DTABLE_PRIVATE_KEY,
                                  algorithm='HS256')
    except Exception as e:
        logger.error(e)
        return render_error(request, _('Internal Server Error'))

    url = '%s/api/v1/dtables/%s/metadata/' % (DTABLE_SERVER_URL.strip('/'),
                                              dtable_uuid)
    req = requests.Request(
        url, headers={"Authorization": "Token %s" % access_token.decode()})

    try:
        dtable_metadata = requests.urlopen(req).read().decode()
    except Exception as e:
        logger.error(e)
        return render_error(request, _('Internal Server Error'))

    share_type = form_obj.share_type
    shared_groups = list()
    if share_type == SHARED_GROUPS:
        group_ids = DTableFormShare.objects.list_by_form(form_obj)
        shared_groups = [{
            'id': group_id,
            'name': group_id_to_name(group_id)
        } for group_id in group_ids]

    return_dict = {
        'dtable_metadata': dtable_metadata,
        'dtable_name': dtable.name,
        'workspace_id': workspace_id,
        'form_id': form_obj.form_id,
        'form_config': form_obj.form_config,
        'dtable_uuid': dtable.uuid.hex,
        'dtable_web_service_url': DTABLE_WEB_SERVICE_URL,
        'form_token': token,
        'share_type': share_type,
        'shared_groups': json.dumps(shared_groups),
    }

    return render(request, 'dtable_edit_form_view_react.html', return_dict)
コード例 #6
0
ファイル: views.py プロジェクト: flazx/dtable-web
def dtable_form_view(request, token):

    # resource check
    form_obj = DTableForms.objects.get_form_by_token(token)
    if not form_obj:
        return render_error(request, 'Table\'s form does not exist.')

    workspace_id = form_obj.workspace_id
    workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
    if not workspace:
        return render_error(request, 'Workspace does not exist.')

    dtable_uuid = form_obj.dtable_uuid
    dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
    if not dtable:
        return render_error(request, 'Table does not exist.')

    # permission check
    if not check_form_submit_permission(request, form_obj):
        return render_permission_error(request, _('Permission denied.'))

    # asset quota check
    if not check_user_workspace_quota(workspace):
        return render_error(request, _('Asset quota exceeded.'))

    # generate json web token
    payload = {
        'exp': int(time.time()) + 60 * 5,
        'dtable_uuid': dtable_uuid,
        'username': "******",
        'permission': PERMISSION_READ,
    }

    try:
        access_token = jwt.encode(payload,
                                  DTABLE_PRIVATE_KEY,
                                  algorithm='HS256')
    except Exception as e:
        logger.error(e)
        return render_error(request, _('Internal Server Error'))

    url = '%s/api/v1/dtables/%s/metadata/' % (DTABLE_SERVER_URL.strip('/'),
                                              dtable_uuid)
    req = requests.Request(
        url, headers={"Authorization": "Token %s" % access_token.decode()})

    try:
        dtable_metadata = requests.urlopen(req).read().decode()
    except Exception as e:
        logger.error(e)
        return render_error(request, _('Internal Server Error'))

    return_dict = {
        'version': SEATABLE_VERSION,
        'dtable_metadata': dtable_metadata,
        'workspace_id': workspace_id,
        'form_id': form_obj.form_id,
        'form_config': form_obj.form_config,
        'dtable_name': dtable.name,
        'dtable_web_service_url': DTABLE_WEB_SERVICE_URL,
        'form_token': token,
    }

    return render(request, 'dtable_share_form_view_react.html', return_dict)
コード例 #7
0
    def get(self, request, workspace_id):
        """get table file upload link

        Permission:
        1. owner
        2. group member
        3. shared user with `rw` or `admin` permission
        """
        # argument check
        table_name = request.GET.get('name', None)
        if not table_name:
            error_msg = 'name invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

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

        dtable = DTables.objects.get_dtable(workspace, table_name)
        if not dtable:
            error_msg = 'dtable %s not found.' % table_name
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        username = request.user.username
        if check_dtable_permission(username, workspace,
                                   dtable) not in WRITE_PERMISSION_TUPLE:
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # quota check
        if not check_user_workspace_quota(workspace):
            error_msg = 'Asset quota exceeded.'
            return api_error(HTTP_443_ABOVE_QUOTA, error_msg)

        # create asset dir
        asset_dir_path = os.path.join('/asset', str(dtable.uuid))
        asset_dir_id = seafile_api.get_dir_id_by_path(repo_id, asset_dir_path)
        if not asset_dir_id:
            seafile_api.mkdir_with_parents(repo_id, '/', asset_dir_path[1:],
                                           username)

        # get token
        obj_id = json.dumps({'parent_dir': asset_dir_path})
        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            obj_id,
                                                            'upload',
                                                            '',
                                                            use_onetime=False)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        upload_link = gen_file_upload_url(token, 'upload-api')

        dtable.modifier = username
        dtable.save()

        res = dict()
        res['upload_link'] = upload_link
        res['parent_path'] = asset_dir_path
        res['img_relative_path'] = os.path.join(UPLOAD_IMG_RELATIVE_PATH,
                                                str(datetime.today())[:7])
        res['file_relative_path'] = os.path.join(UPLOAD_FILE_RELATIVE_PATH,
                                                 str(datetime.today())[:7])
        return Response(res)
コード例 #8
0
    def post(self, request, token):
        """Submit a form
        """
        # argument check
        row_data = request.POST.get("row_data", None)
        if not row_data:
            error_msg = 'row_data invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        table_id = request.POST.get("table_id", None)
        if not table_id:
            error_msg = 'table_id invalid.'
            return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

        # resource check
        form_obj = DTableForms.objects.get_form_by_token(token)
        if not form_obj:
            error_msg = 'Form %s not found.' % token
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        workspace_id = form_obj.workspace_id
        workspace = Workspaces.objects.get_workspace_by_id(workspace_id)
        if not workspace:
            error_msg = 'Workspace %s not found.' % workspace_id
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        dtable_uuid = form_obj.dtable_uuid
        dtable = DTables.objects.get_dtable_by_uuid(dtable_uuid)
        if not dtable:
            error_msg = 'Table %s not found.' % dtable_uuid
            return api_error(status.HTTP_404_NOT_FOUND, error_msg)

        # permission check
        if not check_form_submit_permission(request, form_obj):
            error_msg = 'Permission denied.'
            return api_error(status.HTTP_403_FORBIDDEN, error_msg)

        # quota check
        if not check_user_workspace_quota(dtable.workspace):
            error_msg = 'Asset quota exceeded.'
            return api_error(HTTP_443_ABOVE_QUOTA, error_msg)

        # generate json web token
        payload = {
            'exp': int(time.time()) + 60 * 5,
            'dtable_uuid': dtable_uuid,
            'username': "******",
            'permission': PERMISSION_READ_WRITE,
        }

        try:
            access_token = jwt.encode(payload,
                                      settings.DTABLE_PRIVATE_KEY,
                                      algorithm='HS256')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        headers = {"Authorization": "Token %s" % access_token.decode()}

        # get dtable columns from metadata
        metadata_url = '%s/api/v1/dtables/%s/metadata/' % \
            (settings.DTABLE_SERVER_URL.strip('/'), form_obj.dtable_uuid)
        try:
            response = requests.get(metadata_url, headers=headers)
            response = response.json()
            tables = response.get('metadata')['tables']
            table = [table for table in tables if table['_id'] == table_id][0]
            columns = table['columns']
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        # migrate image files from assets/xxx/forms/xxx to assets/xxx/images/xxx
        row_data_dict = json.loads(row_data)
        form_column_keys = [
            col['key'] for col in json.loads(form_obj.form_config)['columns']
        ]
        image_keys = [
            col['key'] for col in columns
            if col['key'] in form_column_keys and col['type'] == 'image'
        ]
        for key in image_keys:
            image_links = row_data_dict.get(key)
            if not image_links:
                continue
            new_links = []
            for link in image_links:
                error, new_link = self._migrate_image(dtable, link.strip())
                if error:
                    return error
                new_links.append(new_link)
            row_data_dict[key] = new_links

        row_data_dict[
            '_creator'] = request.user.username if request.user.is_authenticated(
            ) else 'anonymous'
        row_data_dict['_ctime'] = datetime.utcnow().replace(
            tzinfo=timezone.utc).isoformat(timespec='milliseconds')

        # insert row
        url = '%s/api/v1/dtables/%s/operations/' % \
              (settings.DTABLE_SERVER_URL.strip('/'), form_obj.dtable_uuid)

        operation = {
            "op_type": "insert_row",
            "table_id": table_id,
            "row_data": row_data_dict,
        }

        try:
            req = requests.post(url, json=operation, headers=headers)

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

        form_config = json.loads(form_obj.form_config)
        notification_config = form_config.get('notification_config', {})

        if notification_config and notification_config.get(
                'is_send_notification', False):
            for user in notification_config.get('notification_selected_users',
                                                []):
                try:
                    submit_form.send(sender=None,
                                     dtable_id=dtable.id,
                                     table_id=table_id,
                                     form_name=form_config.get(
                                         'form_name', ''),
                                     submit_user=request.user.username,
                                     to_user=user.get('email', ''))
                except Exception as e:
                    logging.error(e)

        resp = json.loads(req.text) if req.text else {"success": False}
        return Response(resp, status=req.status_code)
コード例 #9
0
ファイル: dtable_api_token.py プロジェクト: flazx/dtable-web
    def get(self, request):
        """get file upload link by dtable api token

        Permission:
        1. valid token
        """
        # argument check
        auth = request.META.get('HTTP_AUTHORIZATION', '').split()
        if not auth or auth[0].lower() != 'token' or len(auth) != 2:
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
        api_token = auth[1]

        # resource check
        try:
            api_token_obj = DTableAPIToken.objects.get_by_token(api_token)
            if not api_token_obj:
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'api token not found.')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error.'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        dtable = api_token_obj.dtable
        table_name = dtable.name
        workspace_id = dtable.workspace_id

        error, workspace, dtable = _resource_check(workspace_id, table_name)
        if error:
            return error

        if not check_user_workspace_quota(workspace):
            return api_error(HTTP_443_ABOVE_QUOTA, 'Asset quota exceeded.')

        # create asset dir
        repo_id = workspace.repo_id
        asset_dir_path = '/asset/' + str(dtable.uuid)
        asset_dir_id = seafile_api.get_dir_id_by_path(repo_id, asset_dir_path)
        if not asset_dir_id:
            try:
                seafile_api.mkdir_with_parents(repo_id, '/',
                                               asset_dir_path[1:],
                                               api_token_obj.generated_by)
            except Exception as e:
                logger.error(e)
                error_msg = 'Internal Server Error'
                return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                 error_msg)

        # get token
        obj_id = json.dumps({'parent_dir': asset_dir_path})
        try:
            token = seafile_api.get_fileserver_access_token(repo_id,
                                                            obj_id,
                                                            'upload',
                                                            '',
                                                            use_onetime=False)
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        upload_link = gen_file_upload_url(token, 'upload-api')

        api_token_obj.update_last_access()
        res = dict()
        res['upload_link'] = upload_link
        res['parent_path'] = asset_dir_path

        return Response(res)
コード例 #10
0
ファイル: dtable_api_token.py プロジェクト: flazx/dtable-web
    def get(self, request):
        """thirdpart app used dtable api token to get access token and dtable uuid
        """
        # argument check
        token_list = request.META.get('HTTP_AUTHORIZATION', '').split()
        if not token_list or token_list[0].lower() != 'token' or len(
                token_list) != 2:
            return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')

        api_token = token_list[1]

        # main
        try:
            api_token_obj = DTableAPIToken.objects.get_by_token(api_token)
            if api_token_obj is None:
                return api_error(status.HTTP_404_NOT_FOUND,
                                 'api token not found.')

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

        # resource check
        dtable = api_token_obj.dtable

        table_name = dtable.name
        workspace_id = dtable.workspace_id

        error, workspace, dtable = _resource_check(workspace_id, table_name)
        if error:
            return error

        # generate json web token
        payload = {
            'exp':
            int(time.time()) + 86400 * 3,
            'dtable_uuid':
            dtable.uuid.hex,
            'username':
            '',
            'permission':
            api_token_obj.permission
            if check_user_workspace_quota(dtable.workspace) else 'r',
            'app_name':
            api_token_obj.app_name,
        }

        try:
            access_token = jwt.encode(payload,
                                      DTABLE_PRIVATE_KEY,
                                      algorithm='HS256')
        except Exception as e:
            logger.error(e)
            error_msg = 'Internal Server Error'
            return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)

        return Response({
            'app_name': api_token_obj.app_name,
            'access_token': access_token,
            'dtable_uuid': dtable.uuid.hex,
            'dtable_server': DTABLE_SERVER_URL,
            'dtable_socket': DTABLE_SOCKET_URL,
        })