Jimmy Bergman has proposed merging lp:~jimmy-sigint/mailman/restapi_auth into 
lp:mailman.

Requested reviews:
  Mailman Coders (mailman-coders)


In my opinion the REST API needs to be authenticated for the following reasons:

1. Even though it is by default exposed only on localhost, this means that all 
local users can administer mailing-lists instead of only some specific user 
like root.

2. It makes sense to use the REST API for integrating with external systems. 
These external systems will often be on other servers, causing the need for 
exposing the REST API on different interfaces than the loopback interface. For 
this authentication is a requirement.

The change in my branch solves this by adding a single shared username/password 
in the webservice section of the config using the parameters admin_user and 
admin_pass. The API is then changed to require HTTP basic auth using these 
credentials.

-- 
https://code.launchpad.net/~jimmy-sigint/mailman/restapi_auth/+merge/36833
Your team Mailman Coders is requested to review the proposed merge of 
lp:~jimmy-sigint/mailman/restapi_auth into lp:mailman.
=== modified file 'src/mailman/config/schema.cfg'
--- src/mailman/config/schema.cfg	2010-03-28 22:20:10 +0000
+++ src/mailman/config/schema.cfg	2010-09-28 10:01:18 +0000
@@ -298,6 +298,11 @@
 # The API version number for the current API.
 api_version: 3.0
 
+# The administrative username.
+admin_user: restadmin
+
+# The administrative password.
+admin_pass: restpass
 
 [language.master]
 # Template for language definitions.  The section name must be [language.xx]

=== modified file 'src/mailman/rest/root.py'
--- src/mailman/rest/root.py	2010-02-26 01:38:25 +0000
+++ src/mailman/rest/root.py	2010-09-28 10:01:18 +0000
@@ -25,7 +25,8 @@
     ]
 
 
-from restish import http, resource
+from restish import http, resource, guard
+from base64 import b64decode
 
 from mailman.config import config
 from mailman.core.system import system
@@ -36,6 +37,16 @@
 
 
 
+def webservice_auth_checker(request, obj):
+    if "HTTP_AUTHORIZATION" in request.environ and request.environ["HTTP_AUTHORIZATION"].startswith("Basic "):
+        credentials = b64decode(request.environ["HTTP_AUTHORIZATION"][6:])
+        username, password = credentials.split(":", 1)
+
+        if username != config.webservice.admin_user or password != config.webservice.admin_pass:
+            raise guard.GuardError(str("User is not authorized for the REST api."))
+    else:
+        raise guard.GuardError(str("The REST api requires authentication."))
+
 class Root(resource.Resource):
     """The RESTful root resource.
 
@@ -44,11 +55,12 @@
     and we start at 3.0 to match the Mailman version number.  That may not
     always be the case though.
     """
+
     @resource.child(config.webservice.api_version)
+    @guard.guard(webservice_auth_checker)
     def api_version(self, request, segments):
         return TopLevel()
 
-
 class TopLevel(resource.Resource):
     """Top level collections and entries."""
 

_______________________________________________
Mailman-coders mailing list
[email protected]
http://mail.python.org/mailman/listinfo/mailman-coders

Reply via email to