From f8bb55f9c14d6aeac21388ba46d8f7111be9088a Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Sun, 6 Nov 2016 14:44:45 -0800 Subject: [PATCH] auth: Refactor auth backend enabled checking code. --- zerver/models.py | 2 ++ zproject/backends.py | 68 +++++++++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/zerver/models.py b/zerver/models.py index f67f313bcb..0359fe2a91 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -137,6 +137,8 @@ class Realm(ModelReprMixin, models.Model): domain = models.CharField(max_length=40, db_index=True, unique=True) # type: text_type # name is the user-visible identifier for the realm. It has no required # structure. + AUTHENTICATION_FLAGS = [u'Google', u'Email', u'GitHub', u'LDAP', u'Dev', u'RemoteUser'] + name = models.CharField(max_length=40, null=True) # type: Optional[text_type] string_id = models.CharField(max_length=40, unique=True) # type: text_type restricted_to_domain = models.BooleanField(default=False) # type: bool diff --git a/zproject/backends.py b/zproject/backends.py index 6f2709f711..552c0d40e6 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -24,28 +24,42 @@ from social.exceptions import AuthFailed from django.contrib.auth import authenticate from zerver.lib.utils import check_subdomain, get_subdomain -def password_auth_enabled(realm): - # type: (Realm) -> bool - for backend in django.contrib.auth.get_backends(): - if isinstance(backend, EmailAuthBackend): - return True - if isinstance(backend, ZulipLDAPAuthBackend): - return True +def pad_method_dict(method_dict): + # type: (Dict[text_type, bool]) -> Dict[text_type, bool] + """Pads an authentication methods dict to contain all auth backends + supported by the software, regardless of whether they are + configured on this server""" + for key in AUTH_BACKEND_NAME_MAP: + if key not in method_dict: + method_dict[key] = False + return method_dict + +def auth_enabled_helper(backends_to_check, realm): + # type: (List[text_type], Optional[Realm]) -> bool + enabled_method_dict = dict((method, True) for method in Realm.AUTHENTICATION_FLAGS) + pad_method_dict(enabled_method_dict) + for supported_backend in django.contrib.auth.get_backends(): + for backend_name in backends_to_check: + backend = AUTH_BACKEND_NAME_MAP[backend_name] + if enabled_method_dict[backend_name] and isinstance(supported_backend, backend): + return True return False -def dev_auth_enabled(): - # type: () -> bool - for backend in django.contrib.auth.get_backends(): - if isinstance(backend, DevAuthBackend): - return True - return False +def password_auth_enabled(realm=None): + # type: (Optional[Realm]) -> bool + return auth_enabled_helper([u'Email', u'LDAP'], realm) -def google_auth_enabled(): - # type: () -> bool - for backend in django.contrib.auth.get_backends(): - if isinstance(backend, GoogleMobileOauth2Backend): - return True - return False +def dev_auth_enabled(realm=None): + # type: (Optional[Realm]) -> bool + return auth_enabled_helper([u'Dev'], realm) + +def google_auth_enabled(realm=None): + # type: (Optional[Realm]) -> bool + return auth_enabled_helper([u'Google'], realm) + +def github_auth_enabled(realm=None): + # type: (Optional[Realm]) -> bool + return auth_enabled_helper([u'GitHub'], realm) def common_get_active_user_by_email(email, return_data=None): # type: (text_type, Optional[Dict[str, Any]]) -> Optional[UserProfile] @@ -63,13 +77,6 @@ def common_get_active_user_by_email(email, return_data=None): return None return user_profile -def github_auth_enabled(): - # type: () -> bool - for backend in django.contrib.auth.get_backends(): - if isinstance(backend, GitHubAuthBackend): - return True - return False - class ZulipAuthMixin(object): def get_user(self, user_profile_id): # type: (int) -> Optional[UserProfile] @@ -372,3 +379,12 @@ class GitHubAuthBackend(SocialAuthMixin, GithubOAuth2): user_profile = None return self.process_do_auth(user_profile, *args, **kwargs) + +AUTH_BACKEND_NAME_MAP = { + u'Dev': DevAuthBackend, + u'Email': EmailAuthBackend, + u'GitHub': GitHubAuthBackend, + u'Google': GoogleMobileOauth2Backend, + u'LDAP': ZulipLDAPAuthBackend, + u'RemoteUser': ZulipRemoteUserBackend, + } # type: Dict[text_type, Any]