Просмотр исходного кода

Allow attach custom auth handler

Sergey Fursov 12 лет назад
Родитель
Сommit
a91a7790c5
7 измененных файлов с 75 добавлено и 25 удалено
  1. 4 1
      config
  2. 7 3
      radicale/auth/__init__.py
  3. 1 0
      radicale/config.py
  4. 1 13
      tests/__init__.py
  5. 1 0
      tests/custom/__init__.py
  6. 30 0
      tests/custom/auth.py
  7. 31 8
      tests/test_auth.py

+ 4 - 1
config

@@ -47,9 +47,12 @@ stock = utf-8
 
 [auth]
 # Authentication method
-# Value: None | htpasswd | IMAP | LDAP | PAM | courier | http
+# Value: None | htpasswd | IMAP | LDAP | PAM | courier | http | custom
 type = None
 
+# custom auth handler
+custom_handler =
+
 # Htpasswd filename
 htpasswd_filename = /etc/radicale/users
 # Htpasswd encryption method

+ 7 - 3
radicale/auth/__init__.py

@@ -34,13 +34,17 @@ def load():
     log.LOGGER.debug("Authentication type is %s" % auth_type)
     if auth_type == "None":
         return None
+    elif auth_type == 'custom':
+        auth_module = config.get("auth", "custom_handler")
+        __import__(auth_module)
+        module = sys.modules[auth_module]
     else:
         root_module = __import__(
             "auth.%s" % auth_type, globals=globals(), level=2)
         module = getattr(root_module, auth_type)
-        # Override auth.is_authenticated
-        sys.modules[__name__].is_authenticated = module.is_authenticated
-        return module
+    # Override auth.is_authenticated
+    sys.modules[__name__].is_authenticated = module.is_authenticated
+    return module
 
 
 def is_authenticated(user, password):

+ 1 - 0
radicale/config.py

@@ -55,6 +55,7 @@ INITIAL_CONFIG = {
         "stock": "utf-8"},
     "auth": {
         "type": "None",
+        "custom_handler": "",
         "htpasswd_filename": "/etc/radicale/users",
         "htpasswd_encryption": "crypt",
         "imap_hostname": "localhost",

+ 1 - 13
tests/__init__.py

@@ -21,8 +21,6 @@ Tests for Radicale.
 
 """
 
-import base64
-import hashlib
 import os
 import shutil
 import sys
@@ -38,7 +36,6 @@ os.environ["RADICALE_CONFIG"] = os.path.join(os.path.dirname(
     os.path.dirname(__file__)), "config")
 
 from radicale import config
-from radicale.auth import htpasswd
 from .helpers import get_file_content
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy import create_engine
@@ -126,19 +123,10 @@ class GitMultiFileSystem(GitFileSystem, MultiFileSystem):
     """Base class for multifilesystem tests using Git"""
 
 
-class HtpasswdAuthSystem(BaseTest):
+class AuthSystem(BaseTest):
     """Base class to test Radicale with Htpasswd authentication"""
     def setup(self):
-        self.colpath = tempfile.mkdtemp()
-        htpasswd_file_path = os.path.join(self.colpath, ".htpasswd")
-        with open(htpasswd_file_path, "wb") as fd:
-            fd.write(b"tmp:{SHA}" + base64.b64encode(
-                hashlib.sha1(b"bepo").digest()))
-        config.set("auth", "type", "htpasswd")
         self.userpass = "dG1wOmJlcG8="
-        self.application = radicale.Application()
-        htpasswd.FILENAME = htpasswd_file_path
-        htpasswd.ENCRYPTION = "sha1"
 
     def teardown(self):
         config.set("auth", "type", "None")

+ 1 - 0
tests/custom/__init__.py

@@ -0,0 +1 @@
+# coding=utf-8

+ 30 - 0
tests/custom/auth.py

@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+#
+# This file is part of Radicale Server - Calendar Server
+# Copyright © 2008 Nicolas Kandel
+# Copyright © 2008 Pascal Halter
+# Copyright © 2008-2013 Guillaume Ayoub
+#
+# This library is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Radicale.  If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Custom authentication.
+
+Just check username for testing
+
+"""
+
+
+def is_authenticated(user, password):
+    return user == 'tmp'

+ 31 - 8
tests/test_auth.py

@@ -22,22 +22,45 @@ Radicale tests with simple requests and authentication.
 
 """
 
-from nose import with_setup
-from . import HtpasswdAuthSystem
+import base64
+import hashlib
+import os
+import radicale
+import tempfile
+from tests import AuthSystem
+from radicale import config
+from radicale.auth import htpasswd
 
 
-class TestBaseAuthRequests(HtpasswdAuthSystem):
+class TestBaseAuthRequests(AuthSystem):
     """
     Tests basic requests with auth.
 
-    ..note Only htpasswd works at the moment since
-    it requires to spawn processes running servers for
-    others auth methods (ldap).
+    We should setup auth for each type before create Application object
     """
 
-    @with_setup(HtpasswdAuthSystem.setup, HtpasswdAuthSystem.teardown)
     def test_root(self):
-        """Tests a GET request at "/"."""
+        self.colpath = tempfile.mkdtemp()
+        htpasswd_file_path = os.path.join(self.colpath, ".htpasswd")
+        with open(htpasswd_file_path, "wb") as fd:
+            fd.write(b"tmp:{SHA}" + base64.b64encode(
+                hashlib.sha1(b"bepo").digest()))
+        config.set("auth", "type", "htpasswd")
+
+        htpasswd.FILENAME = htpasswd_file_path
+        htpasswd.ENCRYPTION = "sha1"
+
+        self.application = radicale.Application()
+
+        status, headers, answer = self.request(
+            "GET", "/", HTTP_AUTHORIZATION=self.userpass)
+        assert status == 200
+        assert "Radicale works!" in answer
+
+    def test_custom(self):
+        config.set("auth", "type", "custom")
+        config.set("auth", "custom_handler", "tests.custom.auth")
+        self.application = radicale.Application()
         status, headers, answer = self.request(
             "GET", "/", HTTP_AUTHORIZATION=self.userpass)
         assert status == 200