diff --git a/README.md b/README.md index 0502e5009..8c1a08d8f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ passbook logopassbook -======= -![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/5d94b893-6dea-4f68-a8fe-10f1674fc3a9/1?style=flat-square) +![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/passbook/1?style=flat-square) +![Tests](https://img.shields.io/azure-devops/tests/beryjuorg/passbook/1?compact_message&style=flat-square) +![Code Coverage](https://img.shields.io/codecov/c/gh/beryju/passbook?style=flat-square) ![Docker pulls](https://img.shields.io/docker/pulls/beryju/passbook.svg?style=flat-square) ![Docker pulls (gatekeeper)](https://img.shields.io/docker/pulls/beryju/passbook-gatekeeper.svg?style=flat-square) ![Latest version](https://img.shields.io/docker/v/beryju/passbook?sort=semver&style=flat-square) ![LGTM Grade](https://img.shields.io/lgtm/grade/python/github/BeryJu/passbook?style=flat-square) -![Code Coverage](https://img.shields.io/codecov/c/gh/beryju/passbook?style=flat-square) ## What is passbook? diff --git a/passbook/policies/reputation/tasks.py b/passbook/policies/reputation/tasks.py index 916278d94..802e3d195 100644 --- a/passbook/policies/reputation/tasks.py +++ b/passbook/policies/reputation/tasks.py @@ -21,7 +21,6 @@ def save_ip_reputation(): for key in keys: score = cache.get(key) remote_ip = key.replace(CACHE_KEY_IP_PREFIX, "") - print(remote_ip) rep, _ = IPReputation.objects.get_or_create(ip=remote_ip) rep.score = score objects_to_update.append(rep) diff --git a/passbook/policies/utils.py b/passbook/policies/utils.py new file mode 100644 index 000000000..9643fbcc9 --- /dev/null +++ b/passbook/policies/utils.py @@ -0,0 +1,11 @@ +"""Policy Utils""" +from typing import Any, Dict + + +def delete_none_keys(dict_: Dict[Any, Any]) -> Dict[Any, Any]: + """Remove any keys from `dict_` that are None.""" + new_dict = {} + for key, value in dict_.items(): + if value is not None: + new_dict[key] = value + return new_dict diff --git a/passbook/sources/oauth/views/core.py b/passbook/sources/oauth/views/core.py index 23883de01..760c8df56 100644 --- a/passbook/sources/oauth/views/core.py +++ b/passbook/sources/oauth/views/core.py @@ -21,10 +21,12 @@ from passbook.flows.planner import ( ) from passbook.flows.views import SESSION_KEY_PLAN from passbook.lib.utils.urls import redirect_with_qs +from passbook.policies.utils import delete_none_keys from passbook.sources.oauth.auth import AuthorizedServiceBackend from passbook.sources.oauth.clients import BaseOAuthClient, get_client from passbook.sources.oauth.models import OAuthSource, UserOAuthSourceConnection from passbook.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND +from passbook.stages.prompt.stage import PLAN_CONTEXT_PROMPT LOGGER = get_logger() @@ -175,7 +177,6 @@ class OAuthCallback(OAuthClientMixin, View): """Prepare Authentication Plan, redirect user FlowExecutor""" kwargs.update( { - # PLAN_CONTEXT_PENDING_USER: user, # Since we authenticate the user by their token, they have no backend set PLAN_CONTEXT_AUTHENTICATION_BACKEND: "django.contrib.auth.backends.ModelBackend", PLAN_CONTEXT_SSO: True, @@ -249,7 +250,13 @@ class OAuthCallback(OAuthClientMixin, View): % {"source": self.source.name} ), ) - context = self.get_user_enroll_context(source, access, info) + # Trim out all keys that have a value of None, + # so we use `"key" in ` checks in policies + context = { + PLAN_CONTEXT_PROMPT: delete_none_keys( + self.get_user_enroll_context(source, access, info) + ) + } return self.handle_login_flow(source.enrollment_flow, **context) diff --git a/passbook/sources/saml/processors/base.py b/passbook/sources/saml/processors/base.py index c1763bd81..34f6b7e45 100644 --- a/passbook/sources/saml/processors/base.py +++ b/passbook/sources/saml/processors/base.py @@ -15,6 +15,7 @@ from passbook.flows.planner import ( ) from passbook.flows.views import SESSION_KEY_PLAN from passbook.lib.utils.urls import redirect_with_qs +from passbook.policies.utils import delete_none_keys from passbook.providers.saml.utils.encoding import decode_base64_and_inflate from passbook.sources.saml.exceptions import ( MissingSAMLResponse, @@ -153,7 +154,7 @@ class Processor: return self._flow_response( request, self._source.enrollment_flow, - **{PLAN_CONTEXT_PROMPT: name_id_filter}, + **{PLAN_CONTEXT_PROMPT: delete_none_keys(name_id_filter)}, ) def _flow_response(