def test_consistent_output(self, info, key, salt): """For fixed key, salt, info, the output should be constant.""" info_bytes = bytes(info) derived_a = derive_key(key, salt, info_bytes) derived_b = derive_key(key, salt, info_bytes) assert derived_a == derived_b
def test_consistent_output(self, info, key, salt): """For fixed key, salt, info, the output should be constant.""" info_bytes = info.encode("utf-8") derived_a = derive_key(key, salt, info_bytes) derived_b = derive_key(key, salt, info_bytes) assert derived_a == derived_b
def test_different_key_different_output(self, info, key_a, key_b, salt): """If the key is rotated, the output should change.""" assume(key_a != key_b) info_bytes = bytes(info) derived_a = derive_key(key_a, salt, info_bytes) derived_b = derive_key(key_b, salt, info_bytes) assert derived_a != derived_b
def test_different_salt_different_output(self, info, key, salt_a, salt_b): """If the salt is changed, the output should change.""" assume(salt_a != salt_b) info_bytes = bytes(info) derived_a = derive_key(key, salt_a, info_bytes) derived_b = derive_key(key, salt_b, info_bytes) assert derived_a != derived_b
def test_different_key_different_output(self, info, key_a, key_b, salt): """If the key is rotated, the output should change.""" assume(key_a != key_b) info_bytes = info.encode("utf-8") derived_a = derive_key(key_a, salt, info_bytes) derived_b = derive_key(key_b, salt, info_bytes) assert derived_a != derived_b
def test_different_salt_different_output(self, info, key, salt_a, salt_b): """If the salt is changed, the output should change.""" assume(salt_a != salt_b) info_bytes = info.encode("utf-8") derived_a = derive_key(key, salt_a, info_bytes) derived_b = derive_key(key, salt_b, info_bytes) assert derived_a != derived_b
def test_different_info_different_output(self, info_a, info_b, key, salt): """ For fixed key material and salt, derive_key should give different output for differing info parameters. """ assume(info_a != info_b) info_a_bytes = info_a.encode("utf-8") info_b_bytes = info_b.encode("utf-8") derived_a = derive_key(key, salt, info_a_bytes) derived_b = derive_key(key, salt, info_b_bytes) assert derived_a != derived_b
def test_different_info_different_output(self, info_a, info_b, key, salt): """ For fixed key material and salt, derive_key should give different output for differing info parameters. """ assume(info_a != info_b) info_a_bytes = bytes(info_a) info_b_bytes = bytes(info_b) derived_a = derive_key(key, salt, info_a_bytes) derived_b = derive_key(key, salt, info_b_bytes) assert derived_a != derived_b
def missing_secrets(settings): missing = {} if 'secret_key' not in settings: log.warn('No secret key provided: using transient key. Please ' 'configure the secret_key setting or the SECRET_KEY ' 'environment variable!') missing['secret_key'] = os.urandom(64) # If the redis session secret hasn't been set explicitly, derive it from # the global secret key. if 'redis.sessions.secret' not in settings: secret = settings.get('secret_key') if secret is None: secret = missing['secret_key'] missing['redis.sessions.secret'] = derive_key(secret, 'h.session') if 'h.hashids.salt' not in settings: log.warn('No salt provided for hashids: using transient value. This ' 'will result in URLs that are unstable across application ' 'restarts! Configure the h.hashids.salt setting or the ' 'HASHIDS_SALT environment variable!') missing['h.hashids.salt'] = os.urandom(64) return missing
def includeme(config): global DEFAULT_POLICY global WEBSOCKET_POLICY # Set up authsanity settings = config.registry.settings settings['authsanity.source'] = 'cookie' settings['authsanity.cookie.max_age'] = 2592000 settings['authsanity.cookie.httponly'] = True settings['authsanity.secret'] = derive_key(settings['secret_key'], b'h.auth.cookie_secret') config.include('pyramid_authsanity') if config.registry.settings.get('h.proxy_auth'): log.warn('Enabling proxy authentication mode: you MUST ensure that ' 'the X-Forwarded-User request header can ONLY be set by ' 'trusted downstream reverse proxies! Failure to heed this ' 'warning will result in ALL DATA stored by this service ' 'being available to ANYONE!') DEFAULT_POLICY = AuthenticationPolicy(api_policy=TOKEN_POLICY, fallback_policy=PROXY_POLICY) WEBSOCKET_POLICY = MultiAuthenticationPolicy([TOKEN_POLICY, PROXY_POLICY]) # Set the default authentication policy. This can be overridden by modules # that include this one. config.set_authentication_policy(DEFAULT_POLICY) # Allow retrieval of the auth_domain from the request object. config.add_request_method(auth_domain, name='auth_domain', reify=True) # Allow retrieval of the auth token (if present) from the request object. config.add_request_method('.tokens.auth_token', reify=True)
def missing_secrets(settings): missing = {} if "secret_key" not in settings: log.warn( "No secret key provided: using transient key. Please " "configure the secret_key setting or the SECRET_KEY " "environment variable!" ) missing["secret_key"] = os.urandom(64) # If the redis session secret hasn't been set explicitly, derive it from # the global secret key. if "redis.sessions.secret" not in settings: secret = settings.get("secret_key") if secret is None: secret = missing["secret_key"] missing["redis.sessions.secret"] = derive_key(secret, "h.session") if "h.hashids.salt" not in settings: log.warn( "No salt provided for hashids: using transient value. This " "will result in URLs that are unstable across application " "restarts! Configure the h.hashids.salt setting or the " "HASHIDS_SALT environment variable!" ) missing["h.hashids.salt"] = os.urandom(64) return missing
def includeme(config): """A local identity provider.""" # Add a `request.authenticated_user` property. # # N.B. we use `property=True` and not `reify=True` here because it is # important that responsibility for caching user lookups is left to the # UserService and not duplicated here. # # This prevents retried requests (those that raise # `transaction.interfaces.TransientError`) gaining access to a stale # `User` instance. config.add_request_method(authenticated_user, property=True) config.register_service_factory('.services.user_service_factory', name='user') config.register_service_factory('.services.user_signup_service_factory', name='user_signup') config.include('.schemas') config.include('.subscribers') secret = config.registry.settings['secret_key'] derived = derive_key(secret, b'h.accounts') serializer = URLSafeTimedSerializer(derived) config.registry.password_reset_serializer = serializer
def includeme(config): """A local identity provider. Finn's Notes: - A Configurator is used to configure a Pyramid application registry, which is used to map resource types to views. - config refers to a Congigurator object """ # Add a `requesti.user` property. # # N.B. we use `property=True` and not `reify=True` here because it is # important that responsibility for caching user lookups is left to the # UserService and not duplicated here. # # This prevents requests that are retried by pyramid_retry gaining access # to a stale `User` instance. config.add_request_method(get_user, name="user", property=True) config.include(".schemas") secret = config.registry.settings["secret_key"] salt = config.registry.settings["secret_salt"] derived = derive_key(secret, salt, b"h.accounts") serializer = URLSafeTimedSerializer(derived) config.registry.password_reset_serializer = serializer
def includeme(config): global DEFAULT_POLICY global WEBSOCKET_POLICY # Set up authsanity settings = config.registry.settings settings['authsanity.source'] = 'cookie' settings['authsanity.cookie.max_age'] = 2592000 settings['authsanity.cookie.httponly'] = True settings['authsanity.secret'] = derive_key(settings['secret_key'], settings['secret_salt'], b'h.auth.cookie_secret') config.include('pyramid_authsanity') if config.registry.settings.get('h.proxy_auth'): log.warn('Enabling proxy authentication mode: you MUST ensure that ' 'the X-Forwarded-User request header can ONLY be set by ' 'trusted downstream reverse proxies! Failure to heed this ' 'warning will result in ALL DATA stored by this service ' 'being available to ANYONE!') DEFAULT_POLICY = AuthenticationPolicy(api_policy=TOKEN_POLICY, fallback_policy=PROXY_POLICY) WEBSOCKET_POLICY = TOKEN_POLICY # Set the default authentication policy. This can be overridden by modules # that include this one. config.set_authentication_policy(DEFAULT_POLICY) # Allow retrieval of the auth_domain from the request object. config.add_request_method(auth_domain, name='auth_domain', reify=True) # Allow retrieval of the auth token (if present) from the request object. config.add_request_method('.tokens.auth_token', reify=True)
def configure(environ=None, settings=None): if environ is None: environ = os.environ if settings is None: settings = {} for s in SETTINGS: try: result = s(environ) except SettingError as e: log.warn(e) if result is not None: settings.update(result) if 'secret_key' not in settings: log.warn('No secret key provided: using transient key. Please ' 'configure the secret_key setting or the SECRET_KEY ' 'environment variable!') settings['secret_key'] = os.urandom(64) # If the redis session secret hasn't been set explicitly, derive it from # the global secret key. if 'redis.sessions.secret' not in settings: settings['redis.sessions.secret'] = derive_key(settings['secret_key'], b'h.session') # Set up SQLAlchemy debug logging if 'debug_query' in settings: level = logging.INFO if settings['debug_query'] == 'trace': level = logging.DEBUG logging.getLogger('sqlalchemy.engine').setLevel(level) return Configurator(settings=settings)
def includeme(config): registry = config.registry settings = registry.settings session_secret = derive_key(settings['secret_key'], b'h.session') session_factory = SignedCookieSessionFactory(session_secret, httponly=True) config.set_session_factory(session_factory)
def includeme(config): registry = config.registry settings = registry.settings session_secret = derive_key(settings['secret_key'], 'h.session') session_factory = SignedCookieSessionFactory(session_secret, httponly=True) config.set_session_factory(session_factory)
def test_it_produces_correct_result(self, info, key, salt, expected): info_bytes = unhexlify(info) salt_bytes = unhexlify(salt) key_bytes = unhexlify(key) derived = derive_key(key_bytes, salt_bytes, info_bytes) # The test vectors have key lengths above and below the fixed-sized # output of `derive_key`. Only compare the corresponding prefixes. compare_len = min(len(expected), 64 * 2) assert hexlify(derived)[:compare_len] == expected[:compare_len].encode()
def includeme(config): settings = config.registry.settings # By default, derive_key generates a 64-byte (512 bit) secret, which is the # correct length for SHA512-based HMAC as specified by the `hashalg`. factory = SignedCookieSessionFactory( secret=derive_key(settings['secret_key'], b'h.session.cookie_secret'), hashalg='sha512', httponly=True, timeout=3600, ) config.set_session_factory(factory)
def includeme(config): """A local identity provider.""" config.add_request_method( authenticated_user, name='authenticated_user', reify=True) config.include('.schemas') config.include('.subscribers') config.include('.views') secret = config.registry.settings['secret_key'] derived = derive_key(secret, b'h.accounts') serializer = URLSafeTimedSerializer(derived) config.registry.password_reset_serializer = serializer
def includeme(config): settings = config.registry.settings # By default, derive_key generates a 64-byte (512 bit) secret, which is the # correct length for SHA512-based HMAC as specified by the `hashalg`. factory = SignedCookieSessionFactory( secret=derive_key(settings["secret_key"], settings["secret_salt"], b"h.session.cookie_secret"), hashalg="sha512", httponly=True, timeout=3600, ) config.set_session_factory(factory) config.set_csrf_storage_policy(SessionCSRFStoragePolicy())
def includeme(config): """A local identity provider.""" config.add_request_method(authenticated_user, name='authenticated_user', reify=True) config.include('.schemas') config.include('.subscribers') config.include('.views') secret = config.registry.settings['secret_key'] derived = derive_key(secret, b'h.accounts') serializer = URLSafeTimedSerializer(derived) config.registry.password_reset_serializer = serializer
def missing_secrets(settings): missing = {} if 'secret_key' not in settings: log.warn('No secret key provided: using transient key. Please ' 'configure the secret_key setting or the SECRET_KEY ' 'environment variable!') missing['secret_key'] = os.urandom(64) # If the redis session secret hasn't been set explicitly, derive it from # the global secret key. if 'redis.sessions.secret' not in settings: secret = settings.get('secret_key') if secret is None: secret = missing['secret_key'] missing['redis.sessions.secret'] = derive_key(secret, 'h.session') return missing
def includeme(config): # Add a `request.user` property. # # N.B. we use `property=True` and not `reify=True` here because it is # important that responsibility for caching user lookups is left to the # UserService and not duplicated here. # # This prevents requests that are retried by pyramid_retry gaining access # to a stale `User` instance. config.add_request_method(get_user, name="user", property=True) config.include(".schemas") secret = config.registry.settings["secret_key"] salt = config.registry.settings["secret_salt"] derived = derive_key(secret, salt, b"h.accounts") serializer = URLSafeTimedSerializer(derived) config.registry.password_reset_serializer = serializer
def missing_secrets(settings): missing = {} if 'secret_key' not in settings: log.warn('No secret key provided: using transient key. Please ' 'configure the secret_key setting or the SECRET_KEY ' 'environment variable!') missing['secret_key'] = os.urandom(64) # If the redis session secret hasn't been set explicitly, derive it from # the global secret key. if 'redis.sessions.secret' not in settings: secret = settings.get('secret_key') if secret is None: secret = missing['secret_key'] missing['redis.sessions.secret'] = derive_key(secret, b'h.session') return missing
def missing_secrets(settings): missing = {} if "secret_key" not in settings: log.warn( "No secret key provided: using transient key. Please " "configure the secret_key setting or the SECRET_KEY " "environment variable!" ) missing["secret_key"] = os.urandom(64) # If the redis session secret hasn't been set explicitly, derive it from # the global secret key. if "redis.sessions.secret" not in settings: secret = settings.get("secret_key") if secret is None: secret = missing["secret_key"] missing["redis.sessions.secret"] = derive_key(secret, "h.session") return missing
def includeme(config): global DEFAULT_POLICY global WEBSOCKET_POLICY # Set up authsanity settings = config.registry.settings settings["authsanity.source"] = "cookie" settings["authsanity.cookie.max_age"] = 2592000 settings["authsanity.cookie.httponly"] = True settings["authsanity.secret"] = derive_key( settings["secret_key"], settings["secret_salt"], b"h.auth.cookie_secret" ) config.include("pyramid_authsanity") if config.registry.settings.get("h.proxy_auth"): log.warning( "Enabling proxy authentication mode: you MUST ensure that " "the X-Forwarded-User request header can ONLY be set by " "trusted downstream reverse proxies! Failure to heed this " "warning will result in ALL DATA stored by this service " "being available to ANYONE!" ) DEFAULT_POLICY = AuthenticationPolicy( api_policy=API_POLICY, fallback_policy=PROXY_POLICY ) WEBSOCKET_POLICY = TOKEN_POLICY # Set the default authentication policy. This can be overridden by modules # that include this one. config.set_authentication_policy(DEFAULT_POLICY) # Allow retrieval of the authority from the request object. config.add_request_method(default_authority, name="default_authority", reify=True) # Allow retrieval of the auth token (if present) from the request object. config.add_request_method(".tokens.auth_token", reify=True)
def test_it_encodes_str_key_material(self): derived = derive_key('akey', b'somesalt', b'some-info') assert len(derived) == 64
def test_output(self, info, key, salt): info_bytes = bytes(info) derived = derive_key(key, salt, info_bytes) assert len(derived) == 64
def test_output(self, info, key, salt): info_bytes = info.encode("utf-8") derived = derive_key(key, salt, info_bytes) assert len(derived) == 64
def test_it_encodes_str_key_material(self): derived = derive_key("akey", b"somesalt", b"some-info") assert len(derived) == 64
def test_output(self, info, key, salt): info_bytes = info.encode('utf-8') derived = derive_key(key, salt, info_bytes) assert len(derived) == 64