From 2287b9209032fc4204a19a08acd9a36e6f0d3474 Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Mon, 11 Oct 2010 14:11:19 +0200
Subject: [PATCH] http.auth.ReadPasswordFile: Don't read file directly

Reading the file before this function allows for better error
reporting.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 daemons/ganeti-rapi          | 11 +++++++----
 lib/http/auth.py             |  7 +++----
 test/ganeti.http_unittest.py | 33 +++++++++++++--------------------
 3 files changed, 23 insertions(+), 28 deletions(-)

diff --git a/daemons/ganeti-rapi b/daemons/ganeti-rapi
index 525165234..643fcf91c 100755
--- a/daemons/ganeti-rapi
+++ b/daemons/ganeti-rapi
@@ -45,6 +45,7 @@ from ganeti import ssconf
 from ganeti import luxi
 from ganeti import serializer
 from ganeti import compat
+from ganeti import utils
 from ganeti.rapi import connector
 
 import ganeti.http.auth   # pylint: disable-msg=W0611
@@ -102,15 +103,17 @@ class RemoteApiHttpServer(http.auth.HttpServerRequestAuthentication,
     @param filename: Path to file
 
     """
-    if not os.path.isfile(constants.RAPI_USERS_FILE):
-      logging.warning("Users file %s not found", filename)
+    try:
+      contents = utils.ReadFile(filename)
+    except EnvironmentError, err:
+      logging.warning("Error while reading %s: %s", filename, err)
       return False
 
     try:
-      users = http.auth.ReadPasswordFile(filename)
+      users = http.auth.ParsePasswordFile(contents)
     except Exception, err: # pylint: disable-msg=W0703
       # We don't care about the type of exception
-      logging.error("Error while reading %s: %s", filename, err)
+      logging.error("Error while parsing %s: %s", filename, err)
       return False
 
     self._users = users
diff --git a/lib/http/auth.py b/lib/http/auth.py
index f66f54bf9..f6e78202b 100644
--- a/lib/http/auth.py
+++ b/lib/http/auth.py
@@ -27,7 +27,6 @@ import re
 import base64
 import binascii
 
-from ganeti import utils
 from ganeti import compat
 from ganeti import http
 
@@ -287,8 +286,8 @@ class PasswordFileUser(object):
     self.options = options
 
 
-def ReadPasswordFile(file_name):
-  """Reads a password file.
+def ParsePasswordFile(contents):
+  """Parses the contents of a password file.
 
   Lines in the password file are of the following format::
 
@@ -306,7 +305,7 @@ def ReadPasswordFile(file_name):
   """
   users = {}
 
-  for line in utils.ReadFile(file_name).splitlines():
+  for line in contents.splitlines():
     line = line.strip()
 
     # Ignore empty lines and comments
diff --git a/test/ganeti.http_unittest.py b/test/ganeti.http_unittest.py
index 3180c7ca0..76577ea69 100755
--- a/test/ganeti.http_unittest.py
+++ b/test/ganeti.http_unittest.py
@@ -26,6 +26,7 @@ import os
 import unittest
 import time
 import tempfile
+from cStringIO import StringIO
 
 from ganeti import http
 
@@ -290,32 +291,24 @@ class TestHttpServerRequestAuthentication(unittest.TestCase):
           self.assert_(ac.called)
 
 
-class TestReadPasswordFile(testutils.GanetiTestCase):
-  def setUp(self):
-    testutils.GanetiTestCase.setUp(self)
-
-    self.tmpfile = tempfile.NamedTemporaryFile()
-
+class TestReadPasswordFile(unittest.TestCase):
   def testSimple(self):
-    self.tmpfile.write("user1 password")
-    self.tmpfile.flush()
-
-    users = http.auth.ReadPasswordFile(self.tmpfile.name)
+    users = http.auth.ParsePasswordFile("user1 password")
     self.assertEqual(len(users), 1)
     self.assertEqual(users["user1"].password, "password")
     self.assertEqual(len(users["user1"].options), 0)
 
   def testOptions(self):
-    self.tmpfile.write("# Passwords\n")
-    self.tmpfile.write("user1 password\n")
-    self.tmpfile.write("\n")
-    self.tmpfile.write("# Comment\n")
-    self.tmpfile.write("user2 pw write,read\n")
-    self.tmpfile.write("   \t# Another comment\n")
-    self.tmpfile.write("invalidline\n")
-    self.tmpfile.flush()
-
-    users = http.auth.ReadPasswordFile(self.tmpfile.name)
+    buf = StringIO()
+    buf.write("# Passwords\n")
+    buf.write("user1 password\n")
+    buf.write("\n")
+    buf.write("# Comment\n")
+    buf.write("user2 pw write,read\n")
+    buf.write("   \t# Another comment\n")
+    buf.write("invalidline\n")
+
+    users = http.auth.ParsePasswordFile(buf.getvalue())
     self.assertEqual(len(users), 2)
     self.assertEqual(users["user1"].password, "password")
     self.assertEqual(len(users["user1"].options), 0)
-- 
GitLab