def sp_initiated(org_slug=None): if not current_org.get_setting("auth_saml_enabled"): logger.error("SAML Login is not enabled") return redirect(url_for('redash.index', org_slug=org_slug)) saml_client = get_saml_client(current_org) nameid_format = current_org.get_setting('auth_saml_nameid_format') if nameid_format is None or nameid_format == "": nameid_format = NAMEID_FORMAT_TRANSIENT _, info = saml_client.prepare_for_authenticate(nameid_format=nameid_format) redirect_url = None # Select the IdP URL to send the AuthN request to for key, value in info['headers']: if key is 'Location': redirect_url = value response = redirect(redirect_url, code=302) # NOTE: # I realize I _technically_ don't need to set Cache-Control or Pragma: # http://stackoverflow.com/a/5494469 # However, Section 3.2.3.2 of the SAML spec suggests they are set: # http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf # We set those headers here as a "belt and suspenders" approach, # since enterprise environments don't always conform to RFCs response.headers['Cache-Control'] = 'no-cache, no-store' response.headers['Pragma'] = 'no-cache' return response
def sp_initiated(org_slug=None): if not current_org.get_setting("auth_saml_enabled"): logger.error("SAML Login is not enabled") return redirect(url_for("redash.index", org_slug=org_slug)) saml_client = get_saml_client(current_org) nameid_format = current_org.get_setting("auth_saml_nameid_format") if nameid_format is None or nameid_format == "": nameid_format = NAMEID_FORMAT_TRANSIENT _, info = saml_client.prepare_for_authenticate(nameid_format=nameid_format) redirect_url = None # Select the IdP URL to send the AuthN request to for key, value in info["headers"]: if key == "Location": redirect_url = value response = redirect(redirect_url, code=302) # NOTE: # I realize I _technically_ don't need to set Cache-Control or Pragma: # https://stackoverflow.com/a/5494469 # However, Section 3.2.3.2 of the SAML spec suggests they are set: # http://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf # We set those headers here as a "belt and suspenders" approach, # since enterprise environments don't always conform to RFCs response.headers["Cache-Control"] = "no-cache, no-store" response.headers["Pragma"] = "no-cache" return response
def _get_column_lists(columns): date_format = _convert_format(current_org.get_setting("date_format")) datetime_format = _convert_format( "{} {}".format( current_org.get_setting("date_format"), current_org.get_setting("time_format"), ) ) special_types = { TYPE_BOOLEAN: _convert_bool, TYPE_DATE: rpartial(_convert_datetime, date_format), TYPE_DATETIME: rpartial(_convert_datetime, datetime_format), } fieldnames = [] special_columns = dict() for col in columns: fieldnames.append(col["name"]) for col_type in special_types.keys(): if col["type"] == col_type: special_columns[col["name"]] = special_types[col_type] return fieldnames, special_columns
def _convert_datetime(value): if not value: return value parsed = parse_date(value) fmt = _convert_format('{} {}'.format(current_org.get_setting('date_format'), current_org.get_setting('time_format'))) return parsed.strftime(fmt)
def _convert_datetime(value): if not value: return value parsed = parse_date(value) fmt = _convert_format('{} {}'.format( current_org.get_setting('date_format'), current_org.get_setting('time_format'))) return parsed.strftime(fmt)
def _convert_date(value): if not value: return value parsed = parse_date(value) return parsed.strftime(_convert_format(current_org.get_setting('date_format')))
def idp_initiated(org_slug=None): if not current_org.get_setting("auth_saml_enabled"): logger.error("SAML Login is not enabled") return redirect(url_for('redash.index', org_slug=org_slug)) saml_client = get_saml_client(current_org) try: authn_response = saml_client.parse_authn_request_response( request.form['SAMLResponse'], entity.BINDING_HTTP_POST) except Exception: logger.error('Failed to parse SAML response', exc_info=True) flash('SAML login failed. Please try again later.') return redirect(url_for('redash.login', org_slug=org_slug)) authn_response.get_identity() user_info = authn_response.get_subject() email = user_info.text name = "%s %s" % (authn_response.ava['FirstName'][0], authn_response.ava['LastName'][0]) # This is what as known as "Just In Time (JIT) provisioning". # What that means is that, if a user in a SAML assertion # isn't in the user store, we create that user first, then log them in user = create_and_login_user(current_org, name, email) if user is None: return logout_and_redirect_to_index() if 'RedashGroups' in authn_response.ava: group_names = authn_response.ava.get('RedashGroups') user.update_group_assignments(group_names) url = url_for('redash.index', org_slug=org_slug) return redirect(url)
def idp_initiated(org_slug=None): if not current_org.get_setting("auth_saml_enabled"): logger.error("SAML Login is not enabled") return redirect(url_for('redash.index', org_slug=org_slug)) saml_client = get_saml_client(current_org) authn_response = saml_client.parse_authn_request_response( request.form['SAMLResponse'], entity.BINDING_HTTP_POST) authn_response.get_identity() user_info = authn_response.get_subject() email = user_info.text name = "%s %s" % (authn_response.ava['FirstName'][0], authn_response.ava['LastName'][0]) # This is what as known as "Just In Time (JIT) provisioning". # What that means is that, if a user in a SAML assertion # isn't in the user store, we create that user first, then log them in user = create_and_login_user(current_org, name, email) if 'RedashGroups' in authn_response.ava: group_names = authn_response.ava.get('RedashGroups') user.update_group_assignments(group_names) url = url_for('redash.index', org_slug=org_slug) return redirect(url)
def idp_initiated(): if not current_org.get_setting("auth_saml_enabled"): logger.error("SAML Login is not enabled") return redirect(url_for('redash.index')) saml_client = get_saml_client(current_org) authn_response = saml_client.parse_authn_request_response( request.form['SAMLResponse'], entity.BINDING_HTTP_POST) authn_response.get_identity() user_info = authn_response.get_subject() email = user_info.text name = "%s %s" % (authn_response.ava['FirstName'][0], authn_response.ava['LastName'][0]) # This is what as known as "Just In Time (JIT) provisioning". # What that means is that, if a user in a SAML assertion # isn't in the user store, we create that user first, then log them in user = create_and_login_user(current_org, name, email) if 'RedashGroups' in authn_response.ava: group_names = authn_response.ava.get('RedashGroups') user.update_group_assignments(group_names) url = url_for('redash.index') return redirect(url)
def _convert_date(value): if not value: return value parsed = parse_date(value) return parsed.strftime( _convert_format(current_org.get_setting('date_format')))
def _get_column_lists(columns): date_format = _convert_format(current_org.get_setting('date_format')) datetime_format = _convert_format('{} {}'.format(current_org.get_setting('date_format'), current_org.get_setting('time_format'))) special_types = { TYPE_BOOLEAN: _convert_bool, TYPE_DATE: rpartial(_convert_datetime, date_format), TYPE_DATETIME: rpartial(_convert_datetime, datetime_format) } fieldnames = [] special_columns = dict() for col in columns: fieldnames.append(col['name']) for col_type in special_types.keys(): if col['type'] == col_type: special_columns[col['name']] = special_types[col_type] return fieldnames, special_columns
def get_queries(self, search_term): if search_term: results = models.Query.search( search_term, self.current_user.group_ids, self.current_user.id, include_drafts=True, multi_byte_search=current_org.get_setting("multi_byte_search_enabled"), ) else: results = models.Query.all_queries( self.current_user.group_ids, self.current_user.id, include_drafts=True ) return filter_by_tags(results, models.Query.tags)
def get_queries(self, search_term): if search_term: return models.Query.search( search_term, self.current_user.group_ids, self.current_user.id, include_drafts=False, include_archived=True, multi_byte_search=current_org.get_setting("multi_byte_search_enabled"), ) else: return models.Query.all_queries( self.current_user.group_ids, self.current_user.id, include_drafts=False, include_archived=True, )
def idp_initiated(org_slug=None): if not current_org.get_setting("auth_saml_enabled"): logger.error("SAML Login is not enabled") return redirect(url_for("redash.index", org_slug=org_slug)) saml_client = get_saml_client(current_org) try: authn_response = saml_client.parse_authn_request_response( request.form["SAMLResponse"], entity.BINDING_HTTP_POST ) except Exception: logger.error("Failed to parse SAML response", exc_info=True) flash("SAML login failed. Please try again later.") return redirect(url_for("redash.login", org_slug=org_slug)) authn_response.get_identity() user_info = authn_response.get_subject() email = user_info.text # Google SAML auth does not return these FirstName / LastName fields try: name = "%s %s" % (authn_response.ava['FirstName'][0], authn_response.ava['LastName'][0]) except Exception as e: # logger.exception(e) logger.warning("could not fetch FirstName or LastName from SAML response: falling back to email user") name = email.split('@')[0] # This is what as known as "Just In Time (JIT) provisioning". # What that means is that, if a user in a SAML assertion # isn't in the user store, we create that user first, then log them in user = create_and_login_user(current_org, name, email) if user is None: return logout_and_redirect_to_index() if "RedashGroups" in authn_response.ava: group_names = authn_response.ava.get("RedashGroups") user.update_group_assignments(group_names) url = url_for("redash.index", org_slug=org_slug) return redirect(url)