Skip to content

Commit 9a0e7b2

Browse files
authored
Merge pull request #631 from isb-cgc/isb-cgc-prod-sp
Sprint 27 release
2 parents 8e28332 + 2d7dae3 commit 9a0e7b2

File tree

11 files changed

+769
-433
lines changed

11 files changed

+769
-433
lines changed

accounts/sa_utils.py

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,12 @@ def unregister_all_gcp_sa(user_id, gcp_id):
595595
def unregister_sa(user_id, sa_name):
596596
st_logger = StackDriverLogger.build_from_django_settings()
597597

598-
sa = ServiceAccount.objects.get(service_account=sa_name, active=1)
598+
sa = ServiceAccount.objects.get(service_account=sa_name)
599+
# papid multi-clicks on button can cause this sa to be inactive already. Nothing to be done...
600+
if not sa.active:
601+
st_logger.write_struct_log_entry(SERVICE_ACCOUNT_LOG_NAME, {
602+
'message': '[STATUS] Attempted to remove INACTIVE SA {0}'.format(str(sa.service_account))})
603+
return
599604
saads = ServiceAccountAuthorizedDatasets.objects.filter(service_account=sa)
600605

601606
st_logger.write_text_log_entry(SERVICE_ACCOUNT_LOG_NAME, "[STATUS] User {} is unregistering SA {}".format(
@@ -629,7 +634,7 @@ def unregister_sa(user_id, sa_name):
629634
'message': '[ERROR] There was an error in removing SA {0} from Google Group {1}.'.format(
630635
str(saad.service_account.service_account), saad.authorized_dataset.acl_google_group)})
631636
st_logger.write_struct_log_entry(SERVICE_ACCOUNT_LOG_NAME, {
632-
'message': '[ERROR] {}}.'.format(str(e))})
637+
'message': '[ERROR] {}.'.format(str(e))})
633638
logger.error('[ERROR] There was an error in removing SA {0} from Google Group {1}: {2}'.format(
634639
str(saad.service_account.service_account), saad.authorized_dataset.acl_google_group, e))
635640
logger.exception(e)
@@ -1091,10 +1096,10 @@ def demo_process_success(auth, user_id, saml_response):
10911096
st_logger.write_text_log_entry(LOG_NAME_ERA_LOGIN_VIEW,
10921097
"[ERROR] Failed to publish to PubSub topic: {}".format(str(e)))
10931098

1099+
retval.messages.append(warn_message)
10941100
return retval
10951101

10961102

1097-
10981103
def deactivate_nih_add_to_open(user_id, user_email):
10991104
try:
11001105
nih_user = NIH_User.objects.get(user_id=user_id, linked=True)
@@ -1146,3 +1151,33 @@ def get_nih_user_details(user_id):
11461151
return user_details
11471152

11481153

1154+
def verify_user_is_in_gcp(user_id, gcp_id):
1155+
user_in_gcp = False
1156+
user_email = None
1157+
try:
1158+
user_email = User.objects.get(id=user_id).email
1159+
crm_service = get_special_crm_resource()
1160+
1161+
iam_policy = crm_service.projects().getIamPolicy(resource=gcp_id, body={}).execute()
1162+
bindings = iam_policy['bindings']
1163+
for val in bindings:
1164+
members = val['members']
1165+
for member in members:
1166+
if member.startswith('user:'):
1167+
if user_email.lower() == member.split(':')[1].lower():
1168+
user_in_gcp = True
1169+
1170+
except Exception as e:
1171+
user = None
1172+
if type(e) is ObjectDoesNotExist:
1173+
user = str(user_id)
1174+
logger.error("[ERROR] While validating user {} membership in GCP {}:".format(user, gcp_id))
1175+
logger.error("Could not find user with ID {}!".format(user))
1176+
else:
1177+
user = user_email
1178+
logger.error("[ERROR] While validating user {} membership in GCP {}:".format(user, gcp_id))
1179+
logger.exception(e)
1180+
logger.warn("[WARNING] Because we can't confirm if user {} is in GCP {} we must assume they're not.".format(user, gcp_id))
1181+
user_in_gcp = False
1182+
1183+
return user_in_gcp

cohorts/metadata_counting.py

Lines changed: 143 additions & 73 deletions
Large diffs are not rendered by default.

cohorts/metadata_helpers.py

Lines changed: 14 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
from uuid import uuid4
3333
from django.conf import settings
3434

35-
3635
debug = settings.DEBUG # RO global for this file
3736

3837
logger = logging.getLogger('main_logger')
@@ -607,76 +606,23 @@ def format_for_display(item):
607606

608607
return formatted_item
609608

610-
611-
# Builds a BQ API v2 QueryParameter set and WHERE clause string from a set of filters of the form:
612-
# {
613-
# 'field_name': [<value>,...]
614-
# }
615-
# Breaks out '<ATTR> IS NULL'
616-
# 2+ values are converted to IN (<value>,...)
617-
# Filters must already be pre-bucketed or formatted
618-
# TODO: add support for BETWEEN
619-
# TODO: add support for <>=
620-
def build_bq_filter_and_params(filters):
621-
result = {
622-
'filter_string': '',
623-
'parameters': []
624-
}
625-
626-
filter_set = []
627-
628-
for attr, values in filters.items():
629-
filter_string = ''
630-
query_param = {
631-
'name': attr,
632-
'parameterType': {
633-
634-
},
635-
'parameterValue': {
636-
637-
}
638-
}
639-
if 'None' in values:
640-
values.remove('None')
641-
filter_string = "{} IS NULL".format(attr)
642-
643-
if len(values) > 0:
644-
if len(filter_string):
645-
filter_string += " OR "
646-
if len(values) == 1:
647-
# Scalar param
648-
query_param['parameterType']['type'] = ('STRING' if re.compile(ur'[^0-9\.]', re.UNICODE).search(values[0]) else 'INT64')
649-
query_param['parameterValue']['value'] = values[0]
650-
filter_string += "{} = @{}".format(attr, attr)
651-
else:
652-
# Array param
653-
query_param['parameterType']['type'] = "ARRAY"
654-
query_param['parameterValue'] = {'arrayValues': [{'value': x} for x in values]}
655-
query_param['parameterType']['arrayType'] = {'type': ('STRING' if re.compile(ur'[^0-9\.]', re.UNICODE).search(values[0]) else 'INT64')}
656-
filter_string += "{} IN UNNEST(@{})".format(attr,attr)
657-
658-
filter_set.append('({})'.format(filter_string))
659-
result['parameters'].append(query_param)
660-
661-
result['filter_string'] = " AND ".join(filter_set)
662-
663-
return result
664-
665609
# Construct WHERE clauses for BigQuery and CloudSQL based on a set of filters
666610
# If the names of the columns differ across the 2 platforms, the alt_key_map can be
667611
# used to map a filter 'key' to a different column name
668-
def build_where_clause(filters, alt_key_map=False, program=None, for_files=False):
612+
def build_where_clause(filters, alt_key_map=False, program=None, for_files=False, comb_with='OR'):
669613
first = True
670614
query_str = ''
671615
big_query_str = '' # todo: make this work for non-string values -- use {}.format
672616
value_tuple = ()
673617
key_order = []
674618
keyType = None
675-
gene = None
676619

677620
grouped_filters = None
678621

679622
for key, value in filters.items():
623+
gene = None
624+
invert = False
625+
680626
if isinstance(value, dict) and 'values' in value:
681627
value = value['values']
682628

@@ -695,6 +641,7 @@ def build_where_clause(filters, alt_key_map=False, program=None, for_files=False
695641
keyType = key.split(':')[0]
696642
if keyType == 'MUT':
697643
gene = key.split(':')[2]
644+
invert = bool(key.split(':')[3] == 'NOT')
698645
key = key.split(':')[-1]
699646

700647
# Multitable filter lists don't come in as string as they can contain arbitrary text in values
@@ -714,20 +661,20 @@ def build_where_clause(filters, alt_key_map=False, program=None, for_files=False
714661
if first:
715662
first = False
716663
else:
717-
big_query_str += ' AND'
664+
big_query_str += ' {}'.format(comb_with)
718665

719-
big_query_str += " %s = '{hugo_symbol}' AND " % 'Hugo_Symbol'
666+
big_query_str += " (%s = '{hugo_symbol}' AND " % 'Hugo_Symbol'
720667
params['gene'] = gene
721668

722669
if(key == 'category'):
723670
if value == 'any':
724-
big_query_str += '%s IS NOT NULL' % 'Variant_Classification'
671+
big_query_str += '%s IS NOT NULL)' % 'Variant_Classification'
725672
params['var_class'] = ''
726673
else:
727-
big_query_str += '%s IN ({var_class})' % 'Variant_Classification'
674+
big_query_str += '%s {}IN ({var_class}))'.format('Variant_Classification', "NOT " if invert else "")
728675
values = MOLECULAR_CATEGORIES[value]['attrs']
729676
else:
730-
big_query_str += '%s IN ({var_class})' % 'Variant_Classification'
677+
big_query_str += '%s {}IN ({var_class}))'.format('Variant_Classification', "NOT " if invert else "")
731678
values = value
732679

733680
if value != 'any':
@@ -854,7 +801,7 @@ def build_where_clause(filters, alt_key_map=False, program=None, for_files=False
854801

855802

856803
def sql_simple_number_by_200(value, field):
857-
if debug: print >> sys.stderr, 'Called ' + sys._getframe().f_code.co_name
804+
if debug: logger.debug('[DEBUG] Called ' + sys._getframe().f_code.co_name)
858805
result = ''
859806

860807
if isinstance(value, basestring):
@@ -1011,7 +958,7 @@ def sql_bmi_by_ranges(value):
1011958

1012959

1013960
def sql_age_by_ranges(value, bin_by_five=False):
1014-
if debug: print >> sys.stderr,'Called '+sys._getframe().f_code.co_name
961+
if debug: logger.debug('[DEBUG] Called '+sys._getframe().f_code.co_name)
1015962
result = ''
1016963
if isinstance(value, basestring):
1017964
value = [value]
@@ -1064,7 +1011,7 @@ def sql_age_by_ranges(value, bin_by_five=False):
10641011

10651012

10661013
def gql_age_by_ranges(q, key, value):
1067-
if debug: print >> sys.stderr,'Called '+sys._getframe().f_code.co_name
1014+
if debug: logger.debug('[DEBUG] Called '+sys._getframe().f_code.co_name)
10681015
result = ''
10691016
if not isinstance(value, basestring):
10701017
# value is a list of ranges
@@ -1111,7 +1058,7 @@ def submit_bigquery_job(bq_service, project_id, query_body, batch=False):
11111058
job_data = {
11121059
'jobReference': {
11131060
'projectId': project_id,
1114-
'job_id': str(uuid4())
1061+
'jobId': str(uuid4())
11151062
},
11161063
'configuration': {
11171064
'query': {

cohorts/models.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from django.db.models import Q
2525
from django.utils.html import escape
2626
from projects.models import Project, Program, User_Feature_Definitions
27+
from django.core.exceptions import ObjectDoesNotExist
2728
from sharing.models import Shared_Resource
2829
from metadata_helpers import fetch_metadata_value_set, fetch_program_data_types, MOLECULAR_DISPLAY_STRINGS
2930

@@ -301,23 +302,38 @@ def format_filters_for_display(cls, filters):
301302
prog_data_types = None
302303

303304
for cohort_filter in filters:
304-
prog_id = Program.objects.get(name=cohort_filter['program'], is_public=True, active=True).id
305-
if prog_id not in prog_vals:
306-
prog_vals[prog_id] = fetch_metadata_value_set(prog_id)
307-
if prog_id not in prog_dts:
308-
prog_dts[prog_id] = fetch_program_data_types(prog_id, True)
309-
310-
prog_values = prog_vals[prog_id]
311-
prog_data_types = prog_dts[prog_id]
305+
prog = None
306+
prog_id = None
307+
is_private = False
308+
try:
309+
prog_id = Program.objects.get(name=cohort_filter['program'], is_public=True, active=True).id
310+
except ObjectDoesNotExist:
311+
is_private = True
312+
313+
if not is_private:
314+
if prog_id not in prog_vals:
315+
prog_vals[prog_id] = fetch_metadata_value_set(prog_id)
316+
if prog_id not in prog_dts:
317+
prog_dts[prog_id] = fetch_program_data_types(prog_id, True)
318+
319+
prog_values = prog_vals[prog_id]
320+
prog_data_types = prog_dts[prog_id]
312321

313322
if 'MUT:' in cohort_filter['name']:
314-
cohort_filter['displ_name'] = cohort_filter['name'].split(':')[2].upper() + ' [' + cohort_filter['name'].split(':')[1].upper() + ',' + string.capwords(cohort_filter['name'].split(':')[3])
315-
cohort_filter['displ_val'] = (MOLECULAR_DISPLAY_STRINGS['values'][cohort_filter['value']] if cohort_filter['name'].split(':')[3] != 'category' else MOLECULAR_DISPLAY_STRINGS['categories'][cohort_filter['value']]) + ']'
323+
cohort_filter['displ_name'] = ("NOT(" if 'NOT:' in cohort_filter['name'] else '') \
324+
+ cohort_filter['name'].split(':')[2].upper() \
325+
+ ' [' + cohort_filter['name'].split(':')[1].upper() + ',' \
326+
+ string.capwords(cohort_filter['name'].split(':')[-1])
327+
cohort_filter['displ_val'] = (
328+
MOLECULAR_DISPLAY_STRINGS['values'][cohort_filter['value']] if cohort_filter['name'].split(':')[-1] != 'category'
329+
else MOLECULAR_DISPLAY_STRINGS['categories'][cohort_filter['value']]) \
330+
+ ']' \
331+
+ (")" if 'NOT:' in cohort_filter['name'] else '')
316332
elif cohort_filter['name'] == 'data_type':
317333
cohort_filter['displ_name'] = 'Data Type'
318334
cohort_filter['displ_val'] = prog_data_types[cohort_filter['value']]
319335
else:
320-
if cohort_filter['name'] not in prog_values:
336+
if not prog_values or cohort_filter['name'] not in prog_values:
321337
cohort_filter['displ_name'] = cohort_filter['name']
322338
cohort_filter['displ_val'] = cohort_filter['value']
323339
else:

0 commit comments

Comments
 (0)