def test_get_bad_access_token(self): config = {'client_id': 'AAAA', 'client_secret': 'BBBB', 'uri': 'localhost'} az = AuthZero(config) az.access_token = {} with self.assertRaises(Exception) as context: az._authorize(az.default_headers) assert('InvalidAccessToken' == str(context.exception))
def get_auth_zero(): """ Get Auth0 users :return: Auth0 user list """ print('get auth zero') config = {'client_id': client_id, 'client_secret': client_secret, 'uri': client_uri} az = AuthZero(config) az.get_access_token() users = az.get_users(fields="username,user_id,name,email,identities," "groups,picture,nickname,_HRData,created_at," "user_metadata.groups,userinfo,app_metadata.groups,app_metadata.hris," "app_metadata") for user in users: if 'app_metadata' in user: groups = user["app_metadata"]["groups"] for group in groups: auth_group = AuthGroups.query.filter_by(groups=group).first() if not auth_group: auth = AuthGroups(groups=group) db.session.add(auth) db.session.commit() if 'manager' in group: admin = Admin.query.filter_by(emp_id=user['user_id']).first() if not admin: new_admin = Admin(emp_id=user['user_id'], name=user['name'], roles=['Manager']) db.session.add(new_admin) db.session.commit() connection = user['identities'][0]['connection'] if 'Mozilla-LDAP' in connection: # print(f'auth0 user {user}') user_id = user['user_id'] current_user = People.query.filter_by(emp_id=user_id).first() if not current_user: name = user['name'].split() try: manager_email = user['_HRData']['manager_email'] except: manager_email = '' first_name = name[0] last_name = name[-1] country = [item for item in user['groups'] if item[:7] == 'egencia'] person_country = '' if country: person_country = country[0][8:].upper() dnow = datetime.datetime.utcnow() person = People(emp_id=user_id, first_name=first_name, last_name=last_name, email=user['email'], slack_handle='', start_date=user['created_at'], last_modified=dnow, timezone='', country=person_country, manager_id=manager_email, user_opt_out=False, manager_opt_out=False, admin_opt_out=False, created_date=dnow) db.session.add(person) try: db.session.commit() except IntegrityError as error: print('DuplicateKeyError {}'.format(error)) db.session.rollback()
def test_get_rules(self, mock_request): fix_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data/get_rules.json') with open(fix_path) as fd: fix = json.load(fd) mock_request.return_value = fix config = {'client_id': 'AAAA', 'client_secret': 'BBBB', 'uri': 'localhost'} az = AuthZero(config) ret = az.get_rules() assert(isinstance(ret, list)) assert(len(ret)) == 2 assert(isinstance(ret[0], dict)) assert(ret[0].get('id') is not None) assert(ret[0].get('script') is not None) assert(ret[0].get('enabled') is True)
def test_get_auto_renew_access_token(self, mock_get_access_token): fix_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data/access_token.json') with open(fix_path) as fd: fix = json.load(fd) mock_get_access_token.return_value = fix config = {'client_id': 'AAAA', 'client_secret': 'BBBB', 'uri': 'localhost'} az = AuthZero(config) az.access_token = az.get_access_token() az.access_token_valid_until = 0 az.access_token_auto_renew = True az._authorize(az.default_headers)
def __init__( self, client_id, client_secret, authorizer_url, api_type="change", well_known="https://auth.allizom.org/.well-known/mozilla-iam", ): self.logger = self.setup_logging() config = { "client_id": client_id, "client_secret": client_secret, "uri": authorizer_url } self.az = AuthZero(config) self.well_known = cis_profile.WellKnown() wk = self.well_known.get_well_known() self.api_url = wk.api.endpoints[api_type] self.api_audience = wk.api.audience
def test_expired_access_token(self, mock_get_access_token): fix_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'data/access_token.json') with open(fix_path) as fd: fix = json.load(fd) mock_get_access_token.return_value = fix config = {'client_id': 'AAAA', 'client_secret': 'BBBB', 'uri': 'localhost'} az = AuthZero(config) az.access_token = az.get_access_token() az.access_token_valid_until = 0 az.access_token_auto_renew = False with self.assertRaises(Exception) as context: az._authorize(az.default_headers) assert("('InvalidAccessToken', 'The access token has expired')" == str(context.exception))
formatstr = "[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s" logging.basicConfig(format=formatstr, datefmt="%H:%M:%S", stream=sys.stderr) if args.debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) config = DotDict({ 'client_id': args.clientid, 'client_secret': args.clientsecret, 'uri': args.uri }) authzero = AuthZero(config) authzero.get_access_token() logger.debug("Got access token for client_id:{}".format(args.clientid)) # on any error, `authzero` will raise an exception and python will exit with non-zero code # Remote clients loader remote_clients = authzero.get_clients() logger.debug( "Loaded {} remote clients from current Auth0 deployment".format( len(remote_clients))) if not os.path.isdir(args.clients_dir): raise Exception('NotAClientsDirectory' (args.clients_dir)) # Write remote clients back to disk/local
'--rules-dir', default='rules', help='Directory containing rules in Auth0 format') parser.add_argument( '-d', '--dry-run', action='store_true', help="Show what would be done but don't actually make any changes") args = parser.parse_args() config = DotDict({ 'client_id': args.clientid, 'client_secret': args.clientsecret, 'uri': args.uri }) authzero = AuthZero(config) authzero.get_access_token() logger.debug("Got access token for client_id:{}".format(args.clientid)) dry_run_message = 'Dry Run : Action not taken : ' if args.dry_run else '' # on any error, `authzero` will raise an exception and python will exit with non-zero code # Remote rules loader remote_rules = authzero.get_rules() logger.debug("Loaded {} remote rules from current Auth0 deployment".format( len(remote_rules))) # Local rules loader if not os.path.isdir(args.rules_dir): raise Exception('NotARulesDirectory' (args.rules_dir))
parser.add_argument('-s', '--clientsecret', default=credentials.client_secret, required=require_creds, help='Auth0 client secret') parser.add_argument( '--default-client', default='VNGM4quJw3Nhx28j8XKVYmu5LcPMCgAH', help='Default Auth0 client id, needed for login page for example') parser.add_argument('--login-page', required=True, help='Auth0 hosted login page (HTML)') args = parser.parse_args() config = DotDict({ 'client_id': args.clientid, 'client_secret': args.clientsecret, 'uri': args.uri }) authzero = AuthZero(config) authzero.get_access_token() logger.debug("Got access token for client_id:{}".format(args.clientid)) client_attributes = DotDict(dict()) with open(args.login_page, 'r', encoding='utf-8') as fd: client_attributes.custom_login_page = fd.read() # on any error, `authzero` will raise an exception and python will exit with non-zero code ret = authzero.update_client(args.default_client, client_attributes) logger.debug("Default client updated {}".format(json.dumps(ret))) sys.exit(0)
class cisAPI(object): """ This class requires cis_profile and authzero """ def __init__( self, client_id, client_secret, authorizer_url, api_type="change", well_known="https://auth.allizom.org/.well-known/mozilla-iam", ): self.logger = self.setup_logging() config = { "client_id": client_id, "client_secret": client_secret, "uri": authorizer_url } self.az = AuthZero(config) self.well_known = cis_profile.WellKnown() wk = self.well_known.get_well_known() self.api_url = wk.api.endpoints[api_type] self.api_audience = wk.api.audience def setup_logging(self, stream=sys.stderr, level=logging.INFO): formatstr = "[%(asctime)s] %(levelname)s [%(name)s.%(funcName)s:%(lineno)d] %(message)s" logging.basicConfig(format=formatstr, datefmt="%H:%M:%S", stream=stream) logger = logging.getLogger(__name__) logger.setLevel(level) return logger def _check_http_response(self, response): """Check that we got a 2XX response from the server, else bail out""" if (response.status >= 300) or (response.status < 200): self.logger.debug( "_check_http_response() HTTP communication failed: {} {}". format(response.status, response.reason, response.read().decode("utf-8"))) raise Exception("HTTPCommunicationFailed", (response.status, response.reason)) def post_profiles(self, profiles): """ @profiles [] list of profiles as cis_profile.User objects Return server response as {} dict raises HTTPCommunicationFailed on any error """ # Unroll profiles so that we have a list of json documents instead of objects json_profiles = [] for _ in profiles: json_profiles = _.as_json() # This always gets a fresh or cached valid token (we use authzero lib) token_info = self.az.get_access_token() headers = { "authorization": "Bearer {}".format(token_info.access_token), "Content-type": "application/json" } res = requests.post("{}/v2/users", self.api_curl, headers=headers, data=json.dumps(json_profiles)) self._check_http_response(res) ret = json.loads(res.read().decode("utf-8")) return ret
credentials = DotDict({'client_id': '', 'client_secret': '', 'uri': 'auth-dev.mozilla.auth0.com'}) require_creds = True # Arguments parser = argparse.ArgumentParser() parser.add_argument('-u', '--uri', default=credentials.uri, help='URI to Auth0 management API') parser.add_argument('-c', '--clientid', default=credentials.client_id, required=require_creds, help='Auth0 client id') parser.add_argument('-s', '--clientsecret', default=credentials.client_secret, required=require_creds, help='Auth0 client secret') parser.add_argument('-r', '--rules-dir', default='rules', help='Directory containing rules in Auth0 format') parser.add_argument('-b', '--backup-rules-to-directory', type=empty_directory, metavar='DIRECTORY', help='Download all rules from the API and save them to this directory.') parser.add_argument('--delete-all-rules-first-causing-outage', action='store_true', help="Before uploading rules, delete all rules causing an outage") parser.add_argument('-d', '--dry-run', action='store_true', help="Show what would be done but don't actually make any changes") args = parser.parse_args() config = DotDict({'client_id': args.clientid, 'client_secret': args.clientsecret, 'uri': args.uri}) authzero = AuthZero(config) authzero.get_access_token() logger.debug("Got access token for client_id:{}".format(args.clientid)) dry_run_message = 'Dry Run : Action not taken : ' if args.dry_run else '' # on any error, `authzero` will raise an exception and python will exit with non-zero code # Remote rules loader remote_rules = authzero.get_rules() logger.debug("Loaded {} remote rules from current Auth0 deployment".format(len(remote_rules))) if args.backup_rules_to_directory: for rule in remote_rules: js_filename = os.path.join( args.backup_rules_to_directory, '{}.js'.format(rule['name']))
if os.path.exists(args.config): credentials = parse_credential_files([args.config]) args.clientid = credentials.client_id args.clientsecret = credentials.client_secret args.uri = credentials.uri else: logger.error('Credentials file {} does not exist'.format(args.config)) sys.exit(1) if not args.clientid or not args.clientsecret: logger.error('Missing client id and/or client secret') sys.exit(1) authzero = AuthZero({ 'client_id': args.clientid, 'client_secret': args.clientsecret, 'uri': args.uri} ) try: authzero.get_access_token() except Exception: logger.error('Unable to get access token for client_id: {}'.format(args.clientid)) sys.exit(1) logger.debug("Got access token for client_id:{}".format(args.clientid)) dry_run_message = 'Dry Run : Action not taken : ' if args.dry_run else '' # on any error, `authzero` will raise an exception and python will exit with non-zero code # Remote rules loader