-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expire user permissions #72
Changes from 3 commits
837b5f4
28815f5
011ebda
df017ea
3622bbf
b437aba
764d677
2d002ca
e678353
716651c
c8111d4
7ef5429
a195929
b4eb1b3
a5f2c58
e92b419
e98e66b
da46257
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,112 +9,19 @@ | |
from sqlalchemy.sql import text | ||
|
||
from hq_superset.exceptions import HQAPIException | ||
from hq_superset.tests.base_test import HQDBTestCase | ||
from hq_superset.tests.const import ( | ||
TEST_DATASOURCE, | ||
TEST_UCR_CSV_V1, | ||
TEST_UCR_CSV_V2, | ||
) | ||
from hq_superset.tests.utils import MockResponse, OAuthMock, UserMock | ||
from hq_superset.utils import ( | ||
SESSION_USER_DOMAINS_KEY, | ||
get_schema_name_for_domain, | ||
DomainSyncUtil, | ||
get_schema_name_for_domain, | ||
) | ||
|
||
from .base_test import HQDBTestCase | ||
from .const import TEST_DATASOURCE | ||
|
||
|
||
class MockResponse: | ||
def __init__(self, json_data, status_code): | ||
self.json_data = json_data | ||
self.status_code = status_code | ||
|
||
def json(self): | ||
return self.json_data | ||
|
||
@property | ||
def content(self): | ||
return pickle.dumps(self.json_data) | ||
|
||
|
||
class UserMock(): | ||
user_id = '123' | ||
|
||
def get_id(self): | ||
return self.user_id | ||
|
||
|
||
class OAuthMock(): | ||
|
||
def __init__(self): | ||
self.user_json = { | ||
'username': 'testuser1', | ||
'first_name': 'user', | ||
'last_name': '1', | ||
'email': '[email protected]', | ||
} | ||
self.domain_json = { | ||
"objects": [ | ||
{ | ||
"domain_name":"test1", | ||
"project_name":"test1" | ||
}, | ||
{ | ||
"domain_name":"test2", | ||
"project_name":"test 1" | ||
}, | ||
] | ||
} | ||
self.test1_datasources = { | ||
"objects": [ | ||
{ | ||
"id": 'test1_ucr1', | ||
"display_name": 'Test1 UCR1', | ||
}, | ||
{ | ||
"id": 'test1_ucr2', | ||
"display_name": 'Test1 UCR2', | ||
}, | ||
] | ||
} | ||
self.test2_datasources = { | ||
"objects": [ | ||
{ | ||
"id": 'test2_ucr1', | ||
"display_name": 'Test2 UCR1', | ||
} | ||
] | ||
} | ||
self.api_base_url = "https://cchq.org/" | ||
self.user_domain_roles = { | ||
"permissions": {"can_view": True, "can_edit": True}, | ||
"roles": ["Gamma", "sql_lab"], | ||
} | ||
|
||
def authorize_access_token(self): | ||
return {"access_token": "some-key"} | ||
|
||
def get(self, url, token): | ||
return { | ||
'api/v0.5/identity/': MockResponse(self.user_json, 200), | ||
'api/v0.5/user_domains?feature_flag=superset-analytics&can_view_reports=true': MockResponse(self.domain_json, 200), | ||
'a/test1/api/v0.5/ucr_data_source/': MockResponse(self.test1_datasources, 200), | ||
'a/test2/api/v0.5/ucr_data_source/': MockResponse(self.test2_datasources, 200), | ||
'a/test1/api/v0.5/ucr_data_source/test1_ucr1/': MockResponse(TEST_DATASOURCE, 200), | ||
'a/test1/configurable_reports/data_sources/export/test1_ucr1/?format=csv': MockResponse(TEST_UCR_CSV_V1, 200), | ||
'a/test1/api/v0.5/analytics-roles/': MockResponse(self.user_domain_roles, 200), | ||
'a/test2/api/v0.5/analytics-roles/': MockResponse(self.user_domain_roles, 200), | ||
}[url] | ||
|
||
|
||
TEST_UCR_CSV_V1 = """\ | ||
doc_id,inserted_at,data_visit_date_eaece89e,data_visit_number_33d63739,data_lmp_date_5e24b993,data_visit_comment_fb984fda | ||
a1, 2021-12-20, 2022-01-19, 100, 2022-02-20, some_text | ||
a2, 2021-12-22, 2022-02-19, 10, 2022-03-20, some_other_text | ||
""" | ||
|
||
TEST_UCR_CSV_V2 = """\ | ||
doc_id,inserted_at,data_visit_date_eaece89e,data_visit_number_33d63739,data_lmp_date_5e24b993,data_visit_comment_fb984fda | ||
a1, 2021-12-20, 2022-01-19, 100, 2022-02-20, some_text | ||
a2, 2021-12-22, 2022-02-19, 10, 2022-03-20, some_other_text | ||
a3, 2021-11-22, 2022-01-19, 10, 2022-03-20, some_other_text2 | ||
""" | ||
|
||
|
||
class TestViews(HQDBTestCase): | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import pickle | ||
|
||
from hq_superset.tests.const import TEST_DATASOURCE, TEST_UCR_CSV_V1 | ||
|
||
|
||
class OAuthMock(object): | ||
|
||
def __init__(self): | ||
self.user_json = { | ||
'username': 'testuser1', | ||
'first_name': 'user', | ||
'last_name': '1', | ||
'email': '[email protected]', | ||
} | ||
self.domain_json = { | ||
"objects": [ | ||
{ | ||
"domain_name":"test1", | ||
"project_name":"test1" | ||
}, | ||
{ | ||
"domain_name":"test2", | ||
"project_name":"test 1" | ||
}, | ||
] | ||
} | ||
self.test1_datasources = { | ||
"objects": [ | ||
{ | ||
"id": 'test1_ucr1', | ||
"display_name": 'Test1 UCR1', | ||
}, | ||
{ | ||
"id": 'test1_ucr2', | ||
"display_name": 'Test1 UCR2', | ||
}, | ||
] | ||
} | ||
self.test2_datasources = { | ||
"objects": [ | ||
{ | ||
"id": 'test2_ucr1', | ||
"display_name": 'Test2 UCR1', | ||
} | ||
] | ||
} | ||
self.api_base_url = "https://cchq.org/" | ||
self.user_domain_roles = { | ||
"permissions": {"can_view": True, "can_edit": True}, | ||
"roles": ["Gamma", "sql_lab"], | ||
} | ||
|
||
def authorize_access_token(self): | ||
return {"access_token": "some-key"} | ||
|
||
def get(self, url, token): | ||
return { | ||
'api/v0.5/identity/': MockResponse(self.user_json, 200), | ||
'api/v0.5/user_domains?feature_flag=superset-analytics&can_view_reports=true': MockResponse( | ||
self.domain_json, 200 | ||
), | ||
'a/test1/api/v0.5/ucr_data_source/': MockResponse(self.test1_datasources, 200), | ||
'a/test2/api/v0.5/ucr_data_source/': MockResponse(self.test2_datasources, 200), | ||
'a/test1/api/v0.5/ucr_data_source/test1_ucr1/': MockResponse(TEST_DATASOURCE, 200), | ||
'a/test1/configurable_reports/data_sources/export/test1_ucr1/?format=csv': MockResponse( | ||
TEST_UCR_CSV_V1, 200 | ||
), | ||
'a/test1/api/v0.5/analytics-roles/': MockResponse(self.user_domain_roles, 200), | ||
'a/test2/api/v0.5/analytics-roles/': MockResponse(self.user_domain_roles, 200), | ||
}[url] | ||
|
||
|
||
class UserMock(object): | ||
user_id = '123' | ||
|
||
def get_id(self): | ||
return self.user_id | ||
|
||
|
||
class MockResponse: | ||
def __init__(self, json_data, status_code): | ||
self.json_data = json_data | ||
self.status_code = status_code | ||
|
||
def json(self): | ||
return self.json_data | ||
|
||
@property | ||
def content(self): | ||
return pickle.dumps(self.json_data) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,10 @@ | |
from zipfile import ZipFile | ||
|
||
import pandas | ||
import pytz | ||
import sqlalchemy | ||
from cryptography.fernet import Fernet | ||
from flask import current_app | ||
from flask import current_app, session | ||
from flask_login import current_user | ||
from sqlalchemy.sql import TableClause | ||
from superset.utils.database import get_or_create_db | ||
|
@@ -30,6 +31,7 @@ | |
DOMAIN_PREFIX = "hqdomain_" | ||
SESSION_USER_DOMAINS_KEY = "user_hq_domains" | ||
SESSION_OAUTH_RESPONSE_KEY = "oauth_response" | ||
SESSION_DOMAIN_ROLE_LAST_SYNCED_AT = "domain_role_last_synced_at" | ||
|
||
|
||
def get_hq_database(): | ||
|
@@ -151,6 +153,7 @@ def sync_domain_role(self, domain): | |
|
||
self.sm.get_session.add(current_user) | ||
self.sm.get_session.commit() | ||
session['domain_role_last_synced_at'] = datetime_utcnow_naive() | ||
return True | ||
|
||
def _ensure_hq_user_role(self): | ||
|
@@ -415,3 +418,7 @@ def cast_data_for_table( | |
def generate_secret(): | ||
alphabet = string.ascii_letters + string.digits | ||
return ''.join(secrets.choice(alphabet) for __ in range(64)) | ||
|
||
|
||
def datetime_utcnow_naive(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mkangia There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right, I got that backwards, will rename this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
return datetime.utcnow().replace(tzinfo=pytz.UTC) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Seems useful.