grist-core icon indicating copy to clipboard operation
grist-core copied to clipboard

[REST API] Access to some REST API endpoints fails with plugin access token

Open pierrecamilleri opened this issue 1 year ago • 2 comments

Describe the current behavior

I am not sure if this is a bug or a feature, but it looks like a bug to me.

The documentation of the plugin getAccessToken function says :

The returned token can be used to authorize regular REST API calls that access the content of the document.

However, this token does not work for some API endpoints, despite the plugin having complete access to the document.

For instance, at least the /download/csv and /download/table-schema are concerned.

I have not found any workaround (except asking for the user to provide an ApiKey), and my question on the community forum has been left unanswered.

Steps to reproduce

  1. Create a new document with a table "Table1" (hardcoded in script)
  2. Add custom widget to page with url : https://validata-table.gitlab.io/validata-grist-plugin/bug-report.html
  3. Give it full document access
  4. Look at response status and body on widget window : response status 403 and body access denied

I reproduce the widget code here (for reference, and in the case it would not be available in the future).

Widget code
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>onRecords</title>
    <script src="https://docs.getgrist.com/grist-plugin-api.js"></script>
  </head>
  <body>
    <pre id="csv">Waiting for data...</pre>
    <script>
      grist.ready();
      grist.onRecords(async function(records) {
        const tokenInfo = await grist.docApi.getAccessToken({readOnly: true});
        responseData = await fetchCSV(tokenInfo)
        document.getElementById('csv').innerHTML = responseData
      });

      async function fetchCSV(tokenInfo) {
        const queryParams = new URLSearchParams({
          auth: tokenInfo.token,
          tableId: "Table1"
        })

        const url = `${tokenInfo.baseUrl}/download/csv?${queryParams.toString()}`

        responseData = ""

        try {
          const response = await fetch(url);

          responseData += "Request:<a href=\"" + url + "\"> "+ url + "</a>\n"
          responseData += "Response Status:" + response.status + "\n"

          const responseBody = await response.text()

          responseData += "Response Body:" + responseBody + "\n"
        } catch (error) {
          responseData += "Error:" + error
        }

        return responseData
      }
    </script>
  </body>
</html>

Without the auth query parameter, I get a different message {"error":"No view access"}.

Describe the expected behavior

I expect the csv export API endpoint to be available from within the widget, with the access token given as auth query parameter.

Where have you encountered this bug?

pierrecamilleri avatar Nov 15 '24 08:11 pierrecamilleri

@pierrecamilleri sorry this went without response!

I took a look at the behavior and it feels unintended. Digging in, the denial happens not in accessing the data, but in accessing the name of the document. This is denied for me:

/download/csv?tableId=Table1&auth=${token}

but this succeeds

/download/csv?tableId=Table1&auth=${token}&title=zig

(if a title is provided, there's no need to look up the document name to construct a title).

If you wanted to think about how to fix this yourself - the failure happens here: https://github.com/gristlabs/grist-core/blob/8ae04777a05b79c88f4106ba85406e4fbf57fdaa/app/server/lib/DocApi.ts#L1860

and it would be easy to add a test in test/server/lib/AccessTokens.ts

paulfitz avatar Mar 19 '25 17:03 paulfitz

Hello,

I am having a similar issue, someone from the support asked me to reference it here.

Using the token I get from the custom widget script, I am able to read an attachment meta and download the file but I am not able to upload a new attachment:

Using the POST method on /attachments/?auth=${token} results in a 401 status.

You can find an example in the "saveFile" function here: https://github.com/Servant-Cities/grist-integrations/blob/main/widgets/draw-io-editor/script.js

Where I would like the possibility to not rely on text data (in this case the "Raw" column) and instead use attachments with read and write access.

Thank you, Simon

SimonMulquin avatar Mar 31 '25 19:03 SimonMulquin