예제 #1
0
def account_check(username, password, request):
    settings = request.registry.settings
    hmac_secret = settings['userid_hmac_secret']
    cache_key = utils.hmac_digest(hmac_secret, ACCOUNT_CACHE_KEY.format(username))
    cache_ttl = int(settings.get('account_cache_ttl_seconds', 30))
    hashed_password = utils.hmac_digest(cache_key, password)

    # Check cache to see whether somebody has recently logged in with the same
    # username and password.
    cache = request.registry.cache
    cache_result = cache.get(cache_key)

    # Username and password have been verified previously. No need to compare hashes
    if cache_result == hashed_password:
        # Refresh the cache TTL.
        cache.expire(cache_key, cache_ttl)
        return True

    # Back to standard procedure
    parent_id = username
    try:
        existing = request.registry.storage.get(parent_id=parent_id,
                                                collection_id='account',
                                                object_id=username)
    except storage_exceptions.RecordNotFoundError:
        return None

    hashed = existing['password'].encode(encoding='utf-8')
    pwd_str = password.encode(encoding='utf-8')
    # Check if password is valid (it is a very expensive computation)
    if bcrypt.checkpw(pwd_str, hashed):
        cache.set(cache_key, hashed_password, ttl=cache_ttl)
        return True
예제 #2
0
def account_check(username, password, request):
    settings = request.registry.settings
    hmac_secret = settings['userid_hmac_secret']
    cache_key = utils.hmac_digest(hmac_secret,
                                  ACCOUNT_CACHE_KEY.format(username))
    cache_ttl = int(settings.get('account_cache_ttl_seconds', 30))
    hashed_password = utils.hmac_digest(cache_key, password)

    # Check cache to see whether somebody has recently logged in with the same
    # username and password.
    cache = request.registry.cache
    cache_result = cache.get(cache_key)

    # Username and password have been verified previously. No need to compare hashes
    if cache_result == hashed_password:
        # Refresh the cache TTL.
        cache.expire(cache_key, cache_ttl)
        return True

    # Back to standard procedure
    parent_id = username
    try:
        existing = request.registry.storage.get(parent_id=parent_id,
                                                collection_id='account',
                                                object_id=username)
    except storage_exceptions.RecordNotFoundError:
        return None

    hashed = existing['password'].encode(encoding='utf-8')
    pwd_str = password.encode(encoding='utf-8')
    # Check if password is valid (it is a very expensive computation)
    if bcrypt.checkpw(pwd_str, hashed):
        cache.set(cache_key, hashed_password, ttl=cache_ttl)
        return True
예제 #3
0
def user_checker(username, password, request):
    """LDAP user_checker
    Let you validate your Basic Auth users to a configured LDAP server.

    Use it like that::

        config = Configurator(
              authentication_policy=BasicAuthenticationPolicy(check=user_checker))
    """
    settings = request.registry.settings
    cache_ttl = settings['ldap.cache_ttl_seconds']
    hmac_secret = settings['userid_hmac_secret']
    cache_key = utils.hmac_digest(hmac_secret, '%s:%s' % (username, password))

    cache = request.registry.cache
    cache_result = cache.get(cache_key)

    ldap_fqn = settings['ldap.fqn']

    if cache_result is None:
        cm = request.registry.ldap_cm

        try:
            with cm.connection(ldap_fqn.format(mail=username), password):
                cache.set(cache_key, "1", ttl=cache_ttl)
                return []
        except INVALID_CREDENTIALS:
            cache.set(cache_key, "0", ttl=cache_ttl)

    elif cache_result == "1":
        return []

    return None
예제 #4
0
def hawk_sessions(request):
    """Grab the Hawk Session from another Authentication backend."""

    authn = AccountsAuthenticationPolicy()

    user = authn.authenticated_userid(request)

    if user is None:
        response = httpexceptions.HTTPUnauthorized()
        response.headers.update(authn.forget(request))
        return response

    settings = request.registry.settings
    hmac_secret = settings['userid_hmac_secret']
    algorithm = settings['hawk.algorithm']

    token = os.urandom(32).hex()

    hawk_auth = HawkAuth(hawk_session=token, algorithm=algorithm)
    credentials = hawk_auth.credentials

    encoded_id = utils.hmac_digest(hmac_secret,
                                   credentials['id'].decode('utf-8'))
    cache_key = HAWK_SESSION_KEY.format(encoded_id)
    cache_ttl = int(settings['hawk.session_ttl_seconds'])

    session = utils.json.dumps({
        "key": credentials["key"],
        "algorithm": credentials["algorithm"],
        "user_id": user
    })
    request.registry.cache.set(cache_key, session, cache_ttl)
    headers = {'Hawk-Session-Token': token}
    return Response(headers=headers, status_code=201)
예제 #5
0
def reset_password_flow(username, password, request):
    cache_key = get_account_cache_key(username, request.registry)
    hashed_password = utils.hmac_digest(cache_key, password)
    pwd_str = password.encode(encoding="utf-8")

    cached_password = get_cached_reset_password(username, request.registry)
    if not cached_password:
        return None

    # The temporary reset password is only available for changing a user's password.
    if request.method.lower() not in ["post", "put", "patch"]:
        return None

    # Only allow modifying a user account, no other resource.
    uri = utils.strip_uri_prefix(request.path)
    resource_name, _ = utils.view_lookup(request, uri)
    if resource_name != "account":
        return None

    try:
        data = request.json["data"]
    except (ValueError, KeyError):
        return None

    # Request one and only one data field: the `password`.
    if not data or "password" not in data or len(data.keys()) > 1:
        return None

    cached_password_str = cached_password.encode(encoding="utf-8")
    if bcrypt.checkpw(pwd_str, cached_password_str):
        # Remove the temporary reset password from the cache.
        delete_cached_reset_password(username, request.registry)
        cache_account(hashed_password, username, request.registry)
        return True
예제 #6
0
파일: __init__.py 프로젝트: jad837/kinto-1
    def unauthenticated_userid(self, request):
        """Return the userid or ``None`` if token could not be verified.
        """
        settings = request.registry.settings
        hmac_secret = settings["userid_hmac_secret"]

        authorization = request.headers.get("Authorization", "")
        try:
            authmeth, access_token = authorization.split(" ", 1)
        except ValueError:
            return None

        if authmeth.lower() != self.header_type.lower():
            return None

        # XXX JWT Access token
        # https://auth0.com/docs/tokens/access-token#access-token-format

        # Check cache if these tokens were already verified.
        hmac_tokens = core_utils.hmac_digest(hmac_secret, access_token)
        cache_key = f"openid:verify:{hmac_tokens}"
        payload = request.registry.cache.get(cache_key)
        if payload is None:
            # This can take some time.
            payload = self._verify_token(access_token)
            if payload is None:
                return None
        # Save for next time / refresh ttl.
        request.registry.cache.set(cache_key,
                                   payload,
                                   ttl=self.verification_ttl)
        request.bound_data["user_profile"] = payload
        # Extract meaningful field from userinfo (eg. email or sub)
        return payload.get(self.userid_field)
    def _verify_token(self, user_token, request):
        """Verify the token extracted from the Authorization header.

        This method stores the result in two locations to avoid hitting the
        auth remote server as much as possible:

        - on the request object, in case the Pyramid authentication methods
          like `effective_principals()` or `authenticated_userid()` are called
          several times during the request cycle;

        - in the cache backend, to reuse validated token from one request to
          another (during ``cache_ttl_seconds`` seconds.)
        """
        # First check if this request was already verified.
        # `request.bound_data` is an attribute provided by Kinto to store
        # some data that is shared among sub-requests (e.g. default bucket
        # or batch requests)
        key = 'portier_verified_token'
        if key in request.bound_data:
            return request.bound_data[key]

        hmac_secret = request.registry.settings['userid_hmac_secret']
        userID = utils.hmac_digest(hmac_secret, user_token)
        auth_cache = request.registry.cache
        encrypted_email = auth_cache.get("portier:%s" % userID)

        if encrypted_email is None:
            return None

        email = decrypt(encrypted_email, user_token)

        # Save for next call.
        request.bound_data[key] = email

        return email
예제 #8
0
파일: __init__.py 프로젝트: glasserc/kinto
    def unauthenticated_userid(self, request):
        """Return the userid or ``None`` if token could not be verified.
        """
        settings = request.registry.settings
        hmac_secret = settings['userid_hmac_secret']

        authorization = request.headers.get('Authorization', '')
        try:
            authmeth, access_token = authorization.split(' ', 1)
        except ValueError:
            return None

        if authmeth.lower() != self.header_type.lower():
            return None

        # XXX JWT Access token
        # https://auth0.com/docs/tokens/access-token#access-token-format

        # Check cache if these tokens were already verified.
        hmac_tokens = core_utils.hmac_digest(hmac_secret, access_token)
        cache_key = 'openid:verify:{}'.format(hmac_tokens)
        payload = request.registry.cache.get(cache_key)
        if payload is None:
            # This can take some time.
            payload = self._verify_token(access_token)
            if payload is None:
                return None
        # Save for next time / refresh ttl.
        request.registry.cache.set(cache_key, payload, ttl=self.verification_ttl)
        # Extract meaningful field from userinfo (eg. email or sub)
        return payload.get(self.userid_field)
예제 #9
0
def get_account_cache_key(username, registry):
    """Given a username, return the cache key for this account."""
    settings = registry.settings
    hmac_secret = settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(hmac_secret,
                                  ACCOUNT_CACHE_KEY.format(username))
    return cache_key
예제 #10
0
def default_bucket_id(request):
    settings = request.registry.settings
    secret = settings.get("default_bucket_hmac_secret",
                          settings["userid_hmac_secret"])
    # Build the user unguessable bucket_id UUID from its user_id
    digest = hmac_digest(secret, request.prefixed_userid)
    return str(uuid.UUID(digest[:32]))
예제 #11
0
def delete_cached_account(username, registry):
    """Given a username, delete the account key from the cache."""
    hmac_secret = registry.settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(hmac_secret,
                                  ACCOUNT_CACHE_KEY.format(username))
    cache = registry.cache
    cache_result = cache.delete(cache_key)
    return cache_result
예제 #12
0
def get_cached_validation_key(username, registry):
    """Given a username, get the validation key from the cache."""
    hmac_secret = registry.settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(
        hmac_secret, ACCOUNT_VALIDATION_CACHE_KEY.format(username))
    cache = registry.cache
    activation_key = cache.get(cache_key)
    return activation_key
예제 #13
0
    def test_default_bucket_exists_and_has_user_id(self):
        bucket = self.app.get(self.bucket_url, headers=self.headers)
        result = bucket.json
        settings = self.app.app.registry.settings
        hmac_secret = settings["userid_hmac_secret"]
        bucket_id = hmac_digest(hmac_secret, self.principal)[:32]

        self.assertEqual(result["data"]["id"], str(UUID(bucket_id)))
        self.assertEqual(result["permissions"]["write"], [self.principal])
예제 #14
0
    def test_default_bucket_exists_and_has_user_id(self):
        bucket = self.app.get(self.bucket_url, headers=self.headers)
        result = bucket.json
        settings = self.app.app.registry.settings
        hmac_secret = settings["userid_hmac_secret"]
        bucket_id = hmac_digest(hmac_secret, self.principal)[:32]

        self.assertEqual(result["data"]["id"], str(UUID(bucket_id)))
        self.assertEqual(result["permissions"]["write"], [self.principal])
예제 #15
0
def delete_cached_reset_password(username, registry):
    """Given a username, delete the reset-password from the cache."""
    hmac_secret = registry.settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(
        hmac_secret, ACCOUNT_RESET_PASSWORD_CACHE_KEY.format(username))

    cache = registry.cache
    cache_result = cache.delete(cache_key)
    return cache_result
예제 #16
0
    def test_default_bucket_exists_and_has_user_id(self):
        bucket = self.app.get(self.bucket_url, headers=self.headers)
        result = bucket.json
        settings = self.app.app.registry.settings
        hmac_secret = settings['userid_hmac_secret']
        bucket_id = hmac_digest(hmac_secret, self.principal)[:32]

        self.assertEqual(result['data']['id'], text_type(UUID(bucket_id)))
        self.assertEqual(result['permissions']['write'], [self.principal])
예제 #17
0
    def _verify_token(self, access_token, request):
        """Verify the token extracted from the Authorization header.

        This method stores the result in two locations to avoid hitting the
        auth remote server as much as possible:

        - on the request object, in case the Pyramid authentication methods
          like `effective_principals()` or `authenticated_userid()` are called
          several times during the request cycle;

        - in the cache backend, to reuse validated token from one request to
          another (during ``cache_ttl_seconds`` seconds.)
        """
        # First check if this request was already verified.
        # `request.bound_data` is an attribute provided by Kinto to store
        # some data that is shared among sub-requests (e.g. default bucket
        # or batch requests)
        if REIFY_KEY not in request.bound_data:
            settings = request.registry.settings
            hmac_secret = settings['userid_hmac_secret']

            cache_ttl = float(facebook_conf(request, 'cache_ttl_seconds'))

            hmac_token = core_utils.hmac_digest(hmac_secret, access_token)
            cache_key = 'facebook:verify:{}'.format(hmac_token)

            payload = request.registry.cache.get(cache_key)

            if payload is None:
                # Verify token from Facebook
                url = facebook_conf(request, 'userinfo_endpoint')
                params = {
                    'input_token': access_token,
                    'access_token': facebook_conf(request, 'app_access_token'),
                }

                # XXX: Implement token validation for Facebook
                resp = requests.get(url, params=params)
                try:
                    resp.raise_for_status()
                except requests.exceptions.HTTPError:
                    logger.exception("Facebook Token Protocol Error")
                    raise httpexceptions.HTTPServiceUnavailable()
                else:
                    body = resp.json()
                    if not body['data']['is_valid']:
                        payload = {}
                    else:
                        payload = body['data']

            request.registry.cache.set(cache_key, payload, ttl=cache_ttl)

            # Save for next call.
            request.bound_data[REIFY_KEY] = payload.get('user_id')

        return request.bound_data[REIFY_KEY]
예제 #18
0
파일: views.py 프로젝트: yanbingms/kinto
def on_account_changed(event):
    request = event.request
    cache = request.registry.cache
    settings = request.registry.settings
    # Extract username and password from current user
    username = request.matchdict["id"]
    hmac_secret = settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(hmac_secret, ACCOUNT_CACHE_KEY.format(username))
    # Delete cache
    cache.delete(cache_key)
예제 #19
0
    def test_default_bucket_hmac_secret_not_define_fallback_to_userid_hmac_secret(
            self):
        settings = self.get_app_settings({"userid_hmac_secret": "secret"})
        if "default_bucket_hmac_secret" in settings:
            del settings["default_bucket_hmac_secret"]
        secret = settings.get("default_bucket_hmac_secret",
                              settings["userid_hmac_secret"])
        value = hmac_digest(secret, "input data")

        self.assertEqual(secret, "secret")
        self.assertTrue(value.startswith("6b9fc51c8e13506e9aee1f4c4bdbb650cd"))
예제 #20
0
    def test_default_bucket_hmac_secret_define(self):
        settings = self.get_app_settings({
            "default_bucket_hmac_secret": "bucket_id_salt",
            "userid_hmac_secret": "secret"
        })
        secret = settings.get("default_bucket_hmac_secret",
                              settings["userid_hmac_secret"])
        value = hmac_digest(secret, "input data")

        self.assertEqual(secret, "bucket_id_salt")
        self.assertTrue(value.startswith("70f09c2d07853887d6b72bc70517f96377"))
예제 #21
0
    def unauthenticated_userid(self, request):
        settings = request.registry.settings

        credentials = base_auth.extract_http_basic_credentials(request)
        if credentials:
            username, password = credentials
            if not username:
                return

            hmac_secret = settings["userid_hmac_secret"]
            credentials = "{}:{}".format(*credentials)
            userid = utils.hmac_digest(hmac_secret, credentials)
            return userid
예제 #22
0
    def unauthenticated_userid(self, request):
        settings = request.registry.settings

        credentials = base_auth.extract_http_basic_credentials(request)
        if credentials:
            username, password = credentials
            if not username:
                return

            hmac_secret = settings['userid_hmac_secret']
            credentials = '{}:{}'.format(*credentials)
            userid = utils.hmac_digest(hmac_secret, credentials)
            return userid
예제 #23
0
    def unauthenticated_userid(self, request):
        settings = request.registry.settings

        credentials = self._get_credentials(request)
        if credentials:
            username, password = credentials
            if not username:
                return

            hmac_secret = settings['userid_hmac_secret']
            credentials = '%s:%s' % credentials
            userid = utils.hmac_digest(hmac_secret, credentials)
            return userid
예제 #24
0
def on_account_changed(event):
    request = event.request
    cache = request.registry.cache
    settings = request.registry.settings
    hmac_secret = settings["userid_hmac_secret"]

    for obj in event.impacted_objects:
        # Extract username and password from current user
        username = obj["old"]["id"]
        cache_key = utils.hmac_digest(hmac_secret,
                                      ACCOUNT_CACHE_KEY.format(username))
        # Delete cache
        cache.delete(cache_key)
예제 #25
0
    def unauthenticated_userid(self, request):
        settings = request.registry.settings

        credentials = base_auth.extract_http_basic_credentials(request)
        if credentials:
            username, password = credentials
            if not username:
                return

            hmac_secret = settings["userid_hmac_secret"]
            credentials = f"{credentials[0]}:{credentials[1]}"
            userid = utils.hmac_digest(hmac_secret, credentials)
            return userid
예제 #26
0
    def setUp(self):
        self.policy = authentication.PortierOAuthAuthenticationPolicy()
        self.backend = memory_backend.Cache(cache_prefix="", cache_max_size_bytes=5123)
        self.user_hmac_secret = random_bytes_hex(16)

        # Setup user
        self.token = '4128913851c9c4305e43dba2a7e59baa5c2fe2b909c6b63d04668346c4fb1e7b'
        self.email = '*****@*****.**'
        encrypted_email = encrypt(self.email, self.token)
        self.user_key = hmac_digest(self.user_hmac_secret, self.token)
        print("portier:%s" % self.user_key)
        self.backend.set("portier:%s" % self.user_key, encrypted_email, ttl=300)
        self.request = self._build_request()
예제 #27
0
    def unauthenticated_userid(self, request):
        settings = request.registry.settings

        credentials = self._get_credentials(request)
        if credentials:
            username, password = credentials
            if not username:
                return

            hmac_secret = settings['userid_hmac_secret']
            credentials = '%s:%s' % credentials
            userid = utils.hmac_digest(hmac_secret, credentials)
            return userid
예제 #28
0
def cache_reset_password(reset_password, username, registry):
    """Store a reset-password in the cache."""
    settings = registry.settings
    hmac_secret = settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(
        hmac_secret, ACCOUNT_RESET_PASSWORD_CACHE_KEY.format(username))
    # Store a reset password for 7 days by default.
    cache_ttl = int(
        settings.get(
            "account_validation.reset_password_cache_ttl_seconds",
            DEFAULT_RESET_PASSWORD_CACHE_TTL_SECONDS,
        ))

    cache = registry.cache
    cache_result = cache.set(cache_key, reset_password, ttl=cache_ttl)
    return cache_result
예제 #29
0
def cache_validation_key(activation_key, username, registry):
    """Store a validation_key in the cache."""
    settings = registry.settings
    hmac_secret = settings["userid_hmac_secret"]
    cache_key = utils.hmac_digest(
        hmac_secret, ACCOUNT_VALIDATION_CACHE_KEY.format(username))
    # Store an activation key for 7 days by default.
    cache_ttl = int(
        settings.get(
            "account_validation.validation_key_cache_ttl_seconds",
            DEFAULT_VALIDATION_KEY_CACHE_TTL_SECONDS,
        ))

    cache = registry.cache
    cache_result = cache.set(cache_key, activation_key, ttl=cache_ttl)
    return cache_result
예제 #30
0
    def test_authentication_refresh_the_cache_each_time_we_authenticate(self):
        hmac_secret = self.app.app.registry.settings["userid_hmac_secret"]
        cache_key = utils.hmac_digest(hmac_secret, ACCOUNT_CACHE_KEY.format("me"))

        self.app.post_json("/accounts", {"data": {"id": "me", "password": "******"}}, status=201)
        resp = self.app.get("/", headers=get_user_headers("me", "bouh"))
        assert resp.json["user"]["id"] == "account:me"

        self.app.app.registry.cache.expire(cache_key, 10)

        resp = self.app.get("/", headers=get_user_headers("me", "bouh"))
        assert resp.json["user"]["id"] == "account:me"

        assert self.app.app.registry.cache.ttl(cache_key) >= 20

        resp = self.app.get("/", headers=get_user_headers("me", "blah"))
        assert "user" not in resp.json
예제 #31
0
    def test_authentication_refresh_the_cache_each_time_we_authenticate(self):
        hmac_secret = self.app.app.registry.settings["userid_hmac_secret"]
        cache_key = utils.hmac_digest(hmac_secret, ACCOUNT_CACHE_KEY.format("me"))

        self.app.post_json("/accounts", {"data": {"id": "me", "password": "******"}}, status=201)
        resp = self.app.get("/", headers=get_user_headers("me", "bouh"))
        assert resp.json["user"]["id"] == "account:me"

        self.app.app.registry.cache.expire(cache_key, 10)

        resp = self.app.get("/", headers=get_user_headers("me", "bouh"))
        assert resp.json["user"]["id"] == "account:me"

        assert self.app.app.registry.cache.ttl(cache_key) >= 20

        resp = self.app.get("/", headers=get_user_headers("me", "blah"))
        assert "user" not in resp.json
예제 #32
0
    def test_authentication_refresh_the_cache_each_time_we_authenticate(self):
        hmac_secret = self.app.app.registry.settings['userid_hmac_secret']
        cache_key = utils.hmac_digest(hmac_secret, ACCOUNT_CACHE_KEY.format('me'))

        self.app.post_json('/accounts', {'data': {'id': 'me', 'password': '******'}},
                           status=201)
        resp = self.app.get('/', headers=get_user_headers('me', 'bouh'))
        assert resp.json['user']['id'] == 'account:me'

        self.app.app.registry.cache.expire(cache_key, 10)

        resp = self.app.get('/', headers=get_user_headers('me', 'bouh'))
        assert resp.json['user']['id'] == 'account:me'

        assert self.app.app.registry.cache.ttl(cache_key) >= 20

        resp = self.app.get('/', headers=get_user_headers('me', 'blah'))
        assert 'user' not in resp.json
예제 #33
0
    def lookup_credentials(self, request, sender_id):
        settings = request.registry.settings
        hmac_secret = settings['userid_hmac_secret']
        algorithm = settings['hawk.algorithm']

        cache_key = HAWK_SESSION_KEY.format(utils.hmac_digest(hmac_secret, sender_id))
        # Check cache to see if we know this session.
        cache = request.registry.cache
        session = cache.get(cache_key)
        cache_ttl = int(settings['hawk.session_ttl_seconds'])

        if session:
            cache.expire(cache_key, cache_ttl)
            request.bound_data['info'] = utils.json.loads(session)
            return {'id': sender_id,
                    'key': request.bound_data['info']['key'],
                    'algorithm': algorithm}

        raise LookupError('unknown sender')
예제 #34
0
def portier_verify(request):
    """Helper to redirect client towards Portier login form."""
    broker_uri = portier_conf(request, 'broker_uri')
    token = request.validated['body']['id_token']
    # Get the data from the config because the request might only
    # have local network information and not the public facing ones.
    audience = '{scheme}://{host}'.format(
        scheme=request.registry.settings['http_scheme'],
        host=request.registry.settings['http_host'])

    try:
        email, stored_redirect = get_verified_email(
            broker_url=broker_uri,
            token=token,
            audience=audience,
            issuer=broker_uri,
            cache=request.registry.cache)
    except ValueError as exc:
        error_details = 'Portier token validation failed: %s' % exc
        return http_error(httpexceptions.HTTPBadRequest(),
                          errno=ERRORS.INVALID_AUTH_TOKEN,
                          error='Invalid Auth Token',
                          message=error_details)

    # Generate a random token
    user_token = codecs.encode(os.urandom(32), 'hex').decode('utf-8')

    # Encrypt the email with the token
    encrypted_email = encrypt(email, user_token)

    # Generate a user ID from the token
    hmac_secret = request.registry.settings['userid_hmac_secret']
    userID = utils.hmac_digest(hmac_secret, user_token)

    # Store the encrypted user ID with the token
    session_ttl = portier_conf(request, 'session_ttl_seconds')
    request.registry.cache.set('portier:' + userID, encrypted_email,
                               session_ttl)

    location = '%s%s' % (stored_redirect, user_token)
    return httpexceptions.HTTPFound(location=location)
예제 #35
0
def account_check(username, password, request):
    settings = request.registry.settings
    validation_enabled = settings.get("account_validation", False)
    cache_key = get_account_cache_key(username, request.registry)
    hashed_password = utils.hmac_digest(cache_key, password)

    # Check cache to see whether somebody has recently logged in with the same
    # username and password.
    cache_result = get_cached_account(username, request.registry)

    # Username and password have been verified previously. No need to compare hashes
    if cache_result == hashed_password:
        # Refresh the cache TTL.
        refresh_cached_account(username, request.registry)
        return True

    # Back to standard procedure
    parent_id = username
    try:
        existing = request.registry.storage.get(parent_id=parent_id,
                                                resource_name="account",
                                                object_id=username)
    except storage_exceptions.ObjectNotFoundError:
        return None

    if validation_enabled and not is_validated(existing):
        return None

    hashed = existing["password"].encode(encoding="utf-8")
    pwd_str = password.encode(encoding="utf-8")
    # Check if password is valid (it is a very expensive computation)
    if bcrypt.checkpw(pwd_str, hashed):
        cache_account(hashed_password, username, request.registry)
        return True

    # Last chance, is this a "reset password" flow?
    return reset_password_flow(username, password, request)
예제 #36
0
 def test_supports_secret_as_bytes(self):
     value = hmac_digest(b"blah", "input data")
     self.assertTrue(value.startswith("d4f5c51db246c7faeb42240545b47274b6"))
예제 #37
0
def user_checker(username, password, request):
    """LDAP user_checker
    Let you validate your Basic Auth users to a configured LDAP server.

    Use it like that::

        config = Configurator(
              authentication_policy=BasicAuthenticationPolicy(check=user_checker))
    """
    settings = request.registry.settings
    cache_ttl = settings['ldap.cache_ttl_seconds']
    hmac_secret = settings['userid_hmac_secret']
    cache_key = utils.hmac_digest(hmac_secret, '{}:{}'.format(username, password))

    cache = request.registry.cache
    cache_result = cache.get(cache_key)

    bind_dn = settings.get('ldap.bind_dn')
    bind_password = settings.get('ldap.bind_password')

    if cache_result is None:
        cm = request.registry.ldap_cm

        # 0. Generate a search filter by combining the attribute and
        # filter provided in the ldap.fqn_filters directive with the
        # username passed by the HTTP client.
        base_dn = settings['ldap.base_dn']
        filters = settings['ldap.filters'].format(mail=username)

        # 1. Search for the user
        try:
            with cm.connection(bind_dn, bind_password) as conn:
                # import pdb; pdb.set_trace()
                results = conn.search_s(base_dn, SCOPE_SUBTREE, filters)
        except BackendError:
            logger.exception("LDAP error")
            return None

        if len(results) != 1:
            # If the search does not return exactly one entry, deny or decline access.
            return None

        dn, entry = results[0]
        user_dn = str(dn)

        # 2. Fetch the distinguished name of the entry retrieved from
        # the search and attempt to bind to the LDAP server using that
        # DN and the password passed by the HTTP client. If the bind
        # is unsuccessful, deny or decline access.
        try:
            with cm.connection(user_dn, password):
                cache.set(cache_key, "1", ttl=cache_ttl)
                return []
        except BackendError:
            logger.exception("LDAP error")
        except INVALID_CREDENTIALS:
            cache.set(cache_key, "0", ttl=cache_ttl)

    elif cache_result == "1":
        return []

    return None
예제 #38
0
 def get_user_id(self, credentials):
     hmac_secret = self.config.get('app:main', 'kinto.userid_hmac_secret')
     credentials = '%s:%s' % credentials
     digest = kinto_core_utils.hmac_digest(hmac_secret, credentials)
     return 'basicauth:%s' % digest
예제 #39
0
def get_default_bucket_id(config, uid):
    secret = config['registry'].settings['userid_hmac_secret']
    digest = hmac_digest(secret, uid)
    return str(uuid.UUID(digest[:32]))
예제 #40
0
파일: __init__.py 프로젝트: glasserc/kinto
def default_bucket_id(request):
    settings = request.registry.settings
    secret = settings['userid_hmac_secret']
    # Build the user unguessable bucket_id UUID from its user_id
    digest = hmac_digest(secret, request.prefixed_userid)
    return str(uuid.UUID(digest[:32]))