def _auth_push_thread(self): info = {"Server": self.server.name} platform_name = None if self.platform == "linux": platform_name = "Linux" elif self.platform == "mac" or self.platform == "ios": platform_name = "Apple" elif self.platform == "win": platform_name = "Windows" elif self.platform == "chrome": platform_name = "Chrome OS" if self.device_name: info["Device"] = "%s (%s)" % (self.device_name, platform_name) if self.push_type == DUO_AUTH: allow, _ = sso.auth_duo(self.user.name, ipaddr=self.remote_ip, type="Connection", info=info) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta(self.user.name, ipaddr=self.remote_ip, type="Connection", info=info) else: raise ValueError("Unkown push auth type") if not allow: self.user.audit_event( "user_connection", ('User connection to "%s" denied. ' + "Push authentication failed") % (self.server.name), remote_addr=self.remote_ip, ) raise AuthError("User failed push authentication")
def duo_auth(): info = { 'Server': self.server.name, } platform_name = None if platform == 'linux': platform_name = 'Linux' elif platform == 'mac': platform_name = 'Apple' elif platform == 'win': platform_name = 'Windows' elif platform == 'chrome': platform_name = 'Chrome OS' if device_name: info['Device'] = '%s (%s)' % (device_name, platform_name) allow = False try: allow, _ = sso.auth_duo( user.name, ipaddr=remote_ip, type='Connection', info=info, ) except: logger.exception( 'Duo server error', 'server', client_id=client_id, user_id=user.id, username=user.name, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Duo server error client_id=%s' % client_id) try: if allow: self.allow_client(client, org, user) else: logger.LogEntry(message='User failed duo ' + 'authentication "%s".' % user.name) self.instance_com.send_client_deny( client_id, key_id, 'User failed duo authentication', ) except: logger.exception( 'Duo auth error', 'server', client_id=client_id, user_id=user.id, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Duo auth error client_id=%s' % client_id)
def duo_auth(): info={ 'Server': self.server.name, } platform_name = None if platform == 'linux': platform_name = 'Linux' elif platform == 'mac': platform_name = 'Apple' elif platform == 'win': platform_name = 'Windows' elif platform == 'chrome': platform_name = 'Chrome OS' if device_name: info['Device'] = '%s (%s)' % ( device_name, platform_name) allow = False try: allow, _ = sso.auth_duo( user.name, ipaddr=remote_ip, type='Connection', info=info, ) except: logger.exception('Duo server error', 'server', client_id=client_id, user_id=user.id, username=user.name, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Duo server error client_id=%s' % client_id) try: if allow: self.allow_client(client, org, user) else: logger.LogEntry(message='User failed duo ' + 'authentication "%s".' % user.name) self.instance_com.send_client_deny( client_id, key_id, 'User failed duo authentication', ) except: logger.exception('Duo auth error', 'server', client_id=client_id, user_id=user.id, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Duo auth error client_id=%s' % client_id)
def auth_check(self, password, otp_code=None, remote_addr=None): if not self.test_password(password): self.audit_event( 'admin_auth', 'Administrator login failed, invalid password', remote_addr=remote_addr, ) return False if self.otp_auth and not self.verify_otp_code(otp_code): self.audit_event( 'admin_auth', 'Administrator login failed, ' + 'invalid two-factor authentication code', remote_addr=remote_addr, ) return False if self.disabled: self.audit_event( 'admin_auth', 'Administrator login failed, administrator is disabled', remote_addr=remote_addr, ) return False sso_admin = settings.app.sso_admin if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin: allow, _ = sso.auth_duo( sso_admin, strong=True, ipaddr=remote_addr, type='Administrator' ) if not allow: self.audit_event( 'admin_auth', 'Administrator login failed, ' + 'failed secondary authentication', remote_addr=remote_addr, ) return False self.audit_event( 'admin_auth', 'Administrator login successful', remote_addr=remote_addr, ) return True
def auth_check(self, password, otp_code=None, remote_addr=None): if not self.test_password(password): self.audit_event( 'admin_auth', 'Administrator login failed, invalid password', remote_addr=remote_addr, ) return False if self.otp_auth and not self.verify_otp_code(otp_code): self.audit_event( 'admin_auth', 'Administrator login failed, ' + 'invalid two-factor authentication code', remote_addr=remote_addr, ) return False if self.disabled: self.audit_event( 'admin_auth', 'Administrator login failed, administrator is disabled', remote_addr=remote_addr, ) return False sso_admin = settings.app.sso_admin if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin: allow, _ = sso.auth_duo(sso_admin, strong=True, ipaddr=remote_addr, type='Administrator') if not allow: self.audit_event( 'admin_auth', 'Administrator login failed, ' + 'failed secondary authentication', remote_addr=remote_addr, ) return False self.audit_event( 'admin_auth', 'Administrator login successful', remote_addr=remote_addr, ) return True
def check_auth(username, password, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify( { '_id': remote_addr, }, { '$inc': { 'count': 1 }, '$setOnInsert': { 'timestamp': utils.now() }, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) administrator = find_user(username=username) if not administrator: return if not administrator.test_password(password): return sso_admin = settings.app.sso_admin if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin: allow, _ = sso.auth_duo(sso_admin, strong=True, ipaddr=remote_addr, type='Administrator') if not allow: return return administrator
def sso_authenticate_post(): if settings.app.sso != DUO_AUTH: return flask.abort(405) username = flask.request.json['username'] usernames = [username] if '@' in username: usernames.append(username.split('@')[0]) valid = False for username in usernames: try: valid, org_id = sso.auth_duo( username, strong=True, ipaddr=flask.request.remote_addr, type='Key', ) except InvalidUser: pass if not valid: return flask.abort(401) if not org_id: org_id = settings.app.sso_org org = organization.get_by_id(org_id) if not org: return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user(name=username, type=CERT_CLIENT, auth_type=DUO_AUTH) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) elif usr.auth_type != DUO_AUTH: usr.auth_type = DUO_AUTH usr.commit('auth_type') key_link = org.create_user_key_link(usr.id, one_time=True) return flask.request.url_root[:-1] + key_link['view_url']
def _auth_push_thread(self): info={ 'Server': self.server.name, } platform_name = None if self.platform == 'linux': platform_name = 'Linux' elif self.platform == 'mac' or self.platform == 'ios': platform_name = 'Apple' elif self.platform == 'win': platform_name = 'Windows' elif self.platform == 'chrome': platform_name = 'Chrome OS' if self.device_name: info['Device'] = '%s (%s)' % (self.device_name, platform_name) if self.push_type == DUO_AUTH: allow, _ = sso.auth_duo( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta_push( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) else: raise ValueError('Unkown push auth type') if not allow: self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % ( self.server.name), remote_addr=self.remote_ip, ) raise AuthError('User failed push authentication')
def _auth_push_thread(self): info = { 'Server': self.server.name, } platform_name = None if self.platform == 'linux': platform_name = 'Linux' elif self.platform == 'mac' or self.platform == 'ios': platform_name = 'Apple' elif self.platform == 'win': platform_name = 'Windows' elif self.platform == 'chrome': platform_name = 'Chrome OS' if self.device_name: info['Device'] = '%s (%s)' % (self.device_name, platform_name) if self.push_type == DUO_AUTH: allow, _ = sso.auth_duo( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta_push( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) else: raise ValueError('Unkown push auth type') if not allow: self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % (self.server.name), remote_addr=self.remote_ip, ) raise AuthError('User failed push authentication')
def check_auth(username, password, remote_addr=None): username = utils.filter_str(username).lower() if remote_addr: doc = Administrator.limiter_collection.find_and_modify({ '_id': remote_addr, }, { '$inc': {'count': 1}, '$setOnInsert': {'timestamp': utils.now()}, }, new=True, upsert=True) if utils.now() > doc['timestamp'] + datetime.timedelta(minutes=1): doc = { 'count': 1, 'timestamp': utils.now(), } Administrator.limiter_collection.update({ '_id': remote_addr, }, doc, upsert=True) if doc['count'] > settings.app.auth_limiter_count_max: raise flask.abort(403) administrator = find_user(username=username) if not administrator: return if not administrator.test_password(password): return sso_admin = settings.app.sso_admin if settings.app.sso and DUO_AUTH in settings.app.sso and sso_admin: allow, _ = sso.auth_duo( sso_admin, strong=True, ipaddr=remote_addr, type='Administrator' ) if not allow: return return administrator
def sso_callback_get(): sso_mode = settings.app.sso if sso_mode not in (GOOGLE_AUTH, GOOGLE_DUO_AUTH, SLACK_AUTH, SLACK_DUO_AUTH, SAML_AUTH, SAML_DUO_AUTH, SAML_OKTA_AUTH, SAML_OKTA_DUO_AUTH, SAML_ONELOGIN_AUTH, SAML_ONELOGIN_DUO_AUTH): return flask.abort(405) state = flask.request.args.get('state') sig = flask.request.args.get('sig') tokens_collection = mongo.get_collection('sso_tokens') doc = tokens_collection.find_and_modify(query={ '_id': state, }, remove=True) if not doc: return flask.abort(404) query = flask.request.query_string.split('&sig=')[0] test_sig = base64.urlsafe_b64encode(hmac.new(str(doc['secret']), query, hashlib.sha512).digest()) if sig != test_sig: return flask.abort(401) params = urlparse.parse_qs(query) if doc.get('type') == SAML_AUTH: username = params.get('username')[0] email = params.get('email', [None])[0] org_name = params.get('org', [None])[0] if not username: return flask.abort(406) valid, org_name = sso.verify_saml(username, email, org_name) if not valid: return flask.abort(401) org_id = settings.app.sso_org if org_name: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id elif doc.get('type') == SLACK_AUTH: username = params.get('username')[0] email = None user_team = params.get('team')[0] org_names = params.get('orgs', [''])[0] org_names = org_names.split(',') valid, org_name = sso.verify_slack(username, user_team, org_names) if not valid: return flask.abort(401) if org_name: org_names = [org_name] org_id = settings.app.sso_org for org_name in org_names: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id break else: username = params.get('username')[0] email = username valid, org_name = sso.verify_google(username) if not valid: return flask.abort(401) org_id = settings.app.sso_org if org_name: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id if DUO_AUTH in sso_mode: valid, _ = sso.auth_duo( username, ipaddr=flask.request.remote_addr, type='Key', ) if not valid: return flask.abort(401) org = organization.get_by_id(org_id) if not org: return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user(name=username, email=email, type=CERT_CLIENT, auth_type=sso_mode) usr.audit_event('user_created', 'User created with single sign-on', remote_addr=utils.get_remote_addr()) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) else: if usr.disabled: return flask.abort(403) if usr.auth_type != sso_mode: usr.auth_type = sso_mode usr.commit('auth_type') key_link = org.create_user_key_link(usr.id, one_time=True) usr.audit_event('user_profile', 'User profile viewed from single sign-on', remote_addr=utils.get_remote_addr(), ) return utils.redirect(utils.get_url_root()[:-1] + key_link['view_url'])
def _auth_push_thread(self): info = { 'Server': self.server.name, } platform_name = None if self.platform == 'linux': platform_name = 'Linux' elif self.platform == 'mac' or self.platform == 'ios': platform_name = 'Apple' elif self.platform == 'win': platform_name = 'Windows' elif self.platform == 'chrome': platform_name = 'Chrome OS' if self.device_name: info['Device'] = '%s (%s)' % (self.device_name, platform_name) if self.push_type == DUO_AUTH: allow, _ = sso.auth_duo( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta_push( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) else: raise ValueError('Unkown push auth type') if not allow: self.user.audit_event( 'user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % (self.server.name), remote_addr=self.remote_ip, ) raise AuthError('User failed push authentication') if settings.app.sso_cache: self.sso_cache_collection.update( { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'timestamp': utils.now(), }, upsert=True)
def sso_authenticate_post(): if settings.app.sso != DUO_AUTH: return flask.abort(405) username = flask.request.json['username'] usernames = [username] email = None if '@' in username: email = username usernames.append(username.split('@')[0]) valid = False for i, username in enumerate(usernames): try: valid, org_id = sso.auth_duo( username, strong=True, ipaddr=flask.request.remote_addr, type='Key', ) break except InvalidUser: if i == len(usernames) - 1: logger.error('Invalid duo username', 'sso', username=username, ) if not valid: logger.error('Invalid duo username', 'sso', username=username, ) return flask.abort(401) if not org_id: org_id = settings.app.sso_org org = organization.get_by_id(org_id) if not org: logger.error('Organization for Duo sso does not exist', 'sso', org_id=org_id, ) return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user(name=username, email=email, type=CERT_CLIENT, auth_type=DUO_AUTH) usr.audit_event('user_created', 'User created with single sign-on', remote_addr=utils.get_remote_addr()) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) else: if usr.disabled: return flask.abort(403) if usr.auth_type != DUO_AUTH: usr.auth_type = DUO_AUTH usr.commit('auth_type') event.Event(type=USERS_UPDATED, resource_id=org.id) key_link = org.create_user_key_link(usr.id, one_time=True) usr.audit_event('user_profile', 'User profile viewed from single sign-on', remote_addr=utils.get_remote_addr(), ) return utils.get_url_root()[:-1] + key_link['view_url']
def _auth_radius(username, password): sso_mode = settings.app.sso valid, org_names, groups = sso.verify_radius(username, password) if not valid: return utils.jsonify({ 'error': AUTH_INVALID, 'error_msg': AUTH_INVALID_MSG, }, 401) org_id = settings.app.sso_org if org_names: for org_name in org_names: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id break valid, org_id_new, groups2 = sso.plugin_sso_authenticate( sso_type='radius', user_name=username, user_email=None, remote_ip=utils.get_remote_addr(), ) if valid: org_id = org_id_new or org_id else: logger.error('Radius plugin authentication not valid', 'sso', username=username, ) return utils.jsonify({ 'error': AUTH_INVALID, 'error_msg': AUTH_INVALID_MSG, }, 401) groups = ((groups or set()) | (groups2 or set())) or None if DUO_AUTH in sso_mode: try: valid, _ = sso.auth_duo( username, ipaddr=utils.get_remote_addr(), type='Key', ) except InvalidUser: logger.error('Duo authentication username not valid', 'sso', username=username, ) return utils.jsonify({ 'error': AUTH_INVALID, 'error_msg': AUTH_INVALID_MSG, }, 401) if valid: valid, org_id_new, groups2 = sso.plugin_sso_authenticate( sso_type='duo', user_name=username, user_email=None, remote_ip=utils.get_remote_addr(), ) if valid: org_id = org_id_new or org_id else: logger.error('Duo plugin authentication not valid', 'sso', username=username, ) return utils.jsonify({ 'error': AUTH_INVALID, 'error_msg': AUTH_INVALID_MSG, }, 401) groups = ((groups or set()) | (groups2 or set())) or None else: logger.error('Duo authentication not valid', 'sso', username=username, ) return utils.jsonify({ 'error': AUTH_INVALID, 'error_msg': AUTH_INVALID_MSG, }, 401) groups = ((groups or set()) | (groups2 or set())) or None org = organization.get_by_id(org_id) if not org: return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user(name=username, type=CERT_CLIENT, auth_type=sso_mode, groups=list(groups) if groups else None) usr.audit_event( 'user_created', 'User created with single sign-on', remote_addr=utils.get_remote_addr(), ) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) else: if usr.disabled: return utils.jsonify({ 'error': AUTH_DISABLED, 'error_msg': AUTH_DISABLED_MSG, }, 403) if groups and groups - set(usr.groups or []): usr.groups = list(set(usr.groups or []) | groups) usr.commit('groups') if usr.auth_type != sso_mode: usr.auth_type = sso_mode usr.set_pin(None) usr.commit(('auth_type', 'pin')) key_link = org.create_user_key_link(usr.id, one_time=True) usr.audit_event('user_profile', 'User profile viewed from single sign-on', remote_addr=utils.get_remote_addr(), ) return utils.jsonify({ 'redirect': utils.get_url_root() + key_link['view_url'], }, 202)
def _auth_push_thread(self): info={ 'Server': self.server.name, } platform_name = None if self.platform == 'linux': platform_name = 'Linux' elif self.platform == 'mac' or self.platform == 'ios': platform_name = 'Apple' elif self.platform == 'win': platform_name = 'Windows' elif self.platform == 'chrome': platform_name = 'Chrome OS' if self.device_name: info['Device'] = '%s (%s)' % (self.device_name, platform_name) if self.push_type == DUO_AUTH: allow, _ = sso.auth_duo( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) elif self.push_type == SAML_OKTA_AUTH: allow = sso.auth_okta_push( self.user.name, ipaddr=self.remote_ip, type='Connection', info=info, ) else: raise ValueError('Unkown push auth type') if not allow: self.user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % ( self.server.name), remote_addr=self.remote_ip, ) raise AuthError('User failed push authentication') if settings.app.sso_cache: self.sso_cache_collection.update({ 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, }, { 'user_id': self.user.id, 'server_id': self.server.id, 'remote_ip': self.remote_ip, 'mac_addr': self.mac_addr, 'platform': self.platform, 'device_id': self.device_id, 'device_name': self.device_name, 'timestamp': utils.now(), }, upsert=True)
def sso_authenticate_post(): if settings.app.sso != DUO_AUTH: return flask.abort(405) username = flask.request.json['username'] usernames = [username] email = None if '@' in username: email = username usernames.append(username.split('@')[0]) valid = False for i, username in enumerate(usernames): try: valid, org_id = sso.auth_duo( username, strong=True, ipaddr=flask.request.remote_addr, type='Key', ) break except InvalidUser: if i == len(usernames) - 1: logger.error('Invalid duo username', 'sso', username=username, ) if not valid: logger.error('Invalid duo username', 'sso', username=username, ) return flask.abort(401) if not org_id: org_id = settings.app.sso_org org = organization.get_by_id(org_id) if not org: logger.error('Organization for Duo sso does not exist', 'sso', org_id=org_id, ) return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user(name=username, email=email, type=CERT_CLIENT, auth_type=DUO_AUTH) usr.audit_event('user_created', 'User created with single sign-on', remote_addr=utils.get_remote_addr()) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) else: if usr.disabled: return flask.abort(403) if usr.auth_type != DUO_AUTH: usr.auth_type = DUO_AUTH usr.commit('auth_type') event.Event(type=USERS_UPDATED, resource_id=org.id) key_link = org.create_user_key_link(usr.id, one_time=True) usr.audit_event('user_profile', 'User profile viewed from single sign-on', remote_addr=utils.get_remote_addr(), ) return flask.request.url_root[:-1] + key_link['view_url']
def auth_thread(): info={ 'Server': self.server.name, } platform_name = None if platform == 'linux': platform_name = 'Linux' elif platform == 'mac': platform_name = 'Apple' elif platform == 'win': platform_name = 'Windows' elif platform == 'chrome': platform_name = 'Chrome OS' if device_name: info['Device'] = '%s (%s)' % (device_name, platform_name) allow = False try: if type == DUO_AUTH: allow, _ = sso.auth_duo( user.name, ipaddr=remote_ip, type='Connection', info=info, ) elif type == SAML_OKTA_AUTH: allow = sso.auth_okta( user.name, ipaddr=remote_ip, type='Connection', info=info, ) else: raise ValueError('Unkown push auth type') except: logger.exception('Push auth server error', 'server', client_id=client_id, user_id=user.id, username=user.name, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Push auth server error client_id=%s' % client_id) try: if allow: self.allow_client(client, org, user, reauth) else: logger.LogEntry(message='User failed push ' + 'authentication "%s".' % user.name) user.audit_event('user_connection', ('User connection to "%s" denied. ' + 'Push authentication failed') % ( self.server.name), remote_addr=remote_ip, ) self.instance_com.send_client_deny( client_id, key_id, 'User failed push authentication', ) except: logger.exception('Push auth error', 'server', client_id=client_id, user_id=user.id, server_id=self.server.id, ) self.instance_com.push_output( 'ERROR Push auth error client_id=%s' % client_id)
def sso_callback_get(): sso_mode = settings.app.sso if sso_mode not in (GOOGLE_AUTH, GOOGLE_DUO_AUTH, SLACK_AUTH, SLACK_DUO_AUTH, SAML_AUTH, SAML_DUO_AUTH, SAML_OKTA_AUTH, SAML_OKTA_DUO_AUTH, SAML_ONELOGIN_AUTH, SAML_ONELOGIN_DUO_AUTH): return flask.abort(405) state = flask.request.args.get('state') sig = flask.request.args.get('sig') tokens_collection = mongo.get_collection('sso_tokens') doc = tokens_collection.find_and_modify(query={ '_id': state, }, remove=True) if not doc: return flask.abort(404) query = flask.request.query_string.split('&sig=')[0] test_sig = base64.urlsafe_b64encode(hmac.new(str(doc['secret']), query, hashlib.sha512).digest()) if sig != test_sig: return flask.abort(401) params = urlparse.parse_qs(query) if doc.get('type') == SAML_AUTH: username = params.get('username')[0] email = params.get('email', [None])[0] org_name = params.get('org', [None])[0] if not username: return flask.abort(406) valid, org_name = sso.verify_saml(username, email, org_name) if not valid: return flask.abort(401) org_id = settings.app.sso_org if org_name: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id elif doc.get('type') == SLACK_AUTH: username = params.get('username')[0] email = None user_team = params.get('team')[0] org_names = params.get('orgs', [''])[0] org_names = org_names.split(',') valid, org_name = sso.verify_slack(username, user_team, org_names) if not valid: return flask.abort(401) if org_name: org_names = [org_name] org_id = settings.app.sso_org for org_name in org_names: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id break else: username = params.get('username')[0] email = username valid, org_name = sso.verify_google(username) if not valid: return flask.abort(401) org_id = settings.app.sso_org if org_name: org = organization.get_by_name(org_name, fields=('_id')) if org: org_id = org.id if DUO_AUTH in sso_mode: valid, _ = sso.auth_duo( username, ipaddr=flask.request.remote_addr, type='Key', ) if not valid: return flask.abort(401) org = organization.get_by_id(org_id) if not org: return flask.abort(405) usr = org.find_user(name=username) if not usr: usr = org.new_user(name=username, email=email, type=CERT_CLIENT, auth_type=sso_mode) usr.audit_event('user_created', 'User created with single sign-on', remote_addr=utils.get_remote_addr()) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) else: if usr.disabled: return flask.abort(403) if usr.auth_type != sso_mode: usr.auth_type = sso_mode usr.commit('auth_type') key_link = org.create_user_key_link(usr.id, one_time=True) usr.audit_event('user_profile', 'User profile viewed from single sign-on', remote_addr=utils.get_remote_addr(), ) return flask.redirect(flask.request.url_root[:-1] + key_link['view_url'])
def sso_callback_get(): sso_mode = settings.app.sso if sso_mode not in (GOOGLE_AUTH, GOOGLE_DUO_AUTH): return flask.abort(405) state = flask.request.args.get('state') user = flask.request.args.get('user') sig = flask.request.args.get('sig') tokens_collection = mongo.get_collection('sso_tokens') doc = tokens_collection.find_and_modify(query={ '_id': state, }, remove=True) if not doc: return flask.abort(404) test_sig = base64.urlsafe_b64encode(hmac.new(str(doc['secret']), str(state + user), hashlib.sha256).digest()) if sig != test_sig: return flask.abort(401) valid, org_id = sso.verify_google(user) if not valid: return flask.abort(401) if sso_mode == GOOGLE_DUO_AUTH: valid, _ = sso.auth_duo( user, ipaddr=flask.request.remote_addr, type='Key', ) if not valid: return flask.abort(401) if not org_id: org_id = settings.app.sso_org org = organization.get_by_id(org_id) if not org: return flask.abort(405) if sso_mode == GOOGLE_DUO_AUTH: auth_type = DUO_AUTH else: auth_type = GOOGLE_AUTH usr = org.find_user(name=user) if not usr: usr = org.new_user(name=user, email=user, type=CERT_CLIENT, auth_type=auth_type) event.Event(type=ORGS_UPDATED) event.Event(type=USERS_UPDATED, resource_id=org.id) event.Event(type=SERVERS_UPDATED) elif usr.auth_type != auth_type: usr.auth_type = auth_type usr.commit('auth_type') key_link = org.create_user_key_link(usr.id, one_time=True) return flask.redirect(flask.request.url_root[:-1] + key_link['view_url'])