This is an automated email from the ASF dual-hosted git repository.

dpgaspar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 26e916e  [api] enable CSRF by default (#9205)
26e916e is described below

commit 26e916e46b1f8b066ef91fdcb2f0dcfc85c83715
Author: Daniel Vaz Gaspar <[email protected]>
AuthorDate: Tue Mar 3 12:22:40 2020 +0000

    [api] enable CSRF by default (#9205)
    
    * [api] Fix, don't exempt CSRF on APIs
    
    * adds cookie based CSRF token support
    
    * blacking
    
    Co-authored-by: ʈᵃᵢ <[email protected]>
---
 .../javascripts/utils/parseCookie_spec.ts}         | 36 +++++++++++++---------
 superset-frontend/src/setup/setupClient.js         |  6 +++-
 .../{setup/setupClient.js => utils/parseCookie.ts} | 22 +++++--------
 superset/views/base_api.py                         |  1 +
 4 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/superset-frontend/src/setup/setupClient.js 
b/superset-frontend/spec/javascripts/utils/parseCookie_spec.ts
similarity index 57%
copy from superset-frontend/src/setup/setupClient.js
copy to superset-frontend/spec/javascripts/utils/parseCookie_spec.ts
index 8a34fb6..1a625ee 100644
--- a/superset-frontend/src/setup/setupClient.js
+++ b/superset-frontend/spec/javascripts/utils/parseCookie_spec.ts
@@ -16,20 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/* eslint no-console: 0 */
-import { SupersetClient } from '@superset-ui/connection';
+import parseCookie from 'src/utils/parseCookie';
 
-export default function setupClient() {
-  const csrfNode = document.querySelector('#csrf_token');
-  const csrfToken = csrfNode ? csrfNode.value : null;
+describe('parseCookie', () => {
+  let cookieVal = '';
+  Object.defineProperty(document, 'cookie', {
+    get: jest.fn().mockImplementation(() => {
+      return cookieVal;
+    }),
+  });
+  it('parses cookie strings', () => {
+    cookieVal = 'val1=foo; val2=bar';
+    expect(parseCookie()).toEqual({ val1: 'foo', val2: 'bar' });
+  });
 
-  SupersetClient.configure({
-    protocol: (window.location && window.location.protocol) || '',
-    host: (window.location && window.location.host) || '',
-    csrfToken,
-  })
-    .init()
-    .catch(error => {
-      console.warn('Error initializing SupersetClient', error);
-    });
-}
+  it('parses empty cookie strings', () => {
+    cookieVal = '';
+    expect(parseCookie()).toEqual({});
+  });
+
+  it('accepts an arg', () => {
+    expect(parseCookie('val=foo')).toEqual({ val: 'foo' });
+  });
+});
diff --git a/superset-frontend/src/setup/setupClient.js 
b/superset-frontend/src/setup/setupClient.js
index 8a34fb6..35e7e75 100644
--- a/superset-frontend/src/setup/setupClient.js
+++ b/superset-frontend/src/setup/setupClient.js
@@ -18,15 +18,19 @@
  */
 /* eslint no-console: 0 */
 import { SupersetClient } from '@superset-ui/connection';
+import parseCookie from 'src/utils/parseCookie';
 
 export default function setupClient() {
   const csrfNode = document.querySelector('#csrf_token');
   const csrfToken = csrfNode ? csrfNode.value : null;
 
+  // when using flask-jwt-extended csrf is set in cookies
+  const cookieCSRFToken = parseCookie().csrf_access_token || '';
+
   SupersetClient.configure({
     protocol: (window.location && window.location.protocol) || '',
     host: (window.location && window.location.host) || '',
-    csrfToken,
+    csrfToken: csrfToken || cookieCSRFToken,
   })
     .init()
     .catch(error => {
diff --git a/superset-frontend/src/setup/setupClient.js 
b/superset-frontend/src/utils/parseCookie.ts
similarity index 61%
copy from superset-frontend/src/setup/setupClient.js
copy to superset-frontend/src/utils/parseCookie.ts
index 8a34fb6..90a4c32 100644
--- a/superset-frontend/src/setup/setupClient.js
+++ b/superset-frontend/src/utils/parseCookie.ts
@@ -16,20 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/* eslint no-console: 0 */
-import { SupersetClient } from '@superset-ui/connection';
 
-export default function setupClient() {
-  const csrfNode = document.querySelector('#csrf_token');
-  const csrfToken = csrfNode ? csrfNode.value : null;
+type CookieMap = { [cookieId: string]: string };
 
-  SupersetClient.configure({
-    protocol: (window.location && window.location.protocol) || '',
-    host: (window.location && window.location.host) || '',
-    csrfToken,
-  })
-    .init()
-    .catch(error => {
-      console.warn('Error initializing SupersetClient', error);
-    });
+export default function parseCookie(cookie = document.cookie): CookieMap {
+  return Object.fromEntries(
+    cookie
+      .split('; ')
+      .filter(x => x)
+      .map(x => x.split('=')),
+  );
 }
diff --git a/superset/views/base_api.py b/superset/views/base_api.py
index 412b5ca..ea9286e 100644
--- a/superset/views/base_api.py
+++ b/superset/views/base_api.py
@@ -63,6 +63,7 @@ class BaseSupersetModelRestApi(ModelRestApi):
     Extends FAB's ModelResApi to implement specific superset generic 
functionality
     """
 
+    csrf_exempt = False
     method_permission_name = {
         "get_list": "list",
         "get": "show",

Reply via email to