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",