1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17  import os 
 18  from zope.interface import Interface, implements 
 19  from buildbot.status.web.base import HtmlResource 
 20   
 22      """Represent an authentication method.""" 
 23   
 25              """Check whether C{user} / C{passwd} are valid.""" 
  26   
 28              """Get the reason authentication failed.""" 
   29   
 35   
 37      implements(IAuth) 
 38      """Implement basic authentication against a list of user/passwd.""" 
 39   
 40      userpass = [] 
 41      """List of user/pass tuples.""" 
 42   
 44          """C{userpass} is a list of (user, passwd).""" 
 45          for item in userpass: 
 46              assert isinstance(item, tuple) 
 47              u, p = item 
 48              assert isinstance(u, str) 
 49              assert isinstance(p, str) 
 50          self.userpass = userpass 
  51   
 53          """Check that C{user}/C{passwd} is a valid user/pass tuple.""" 
 54          if not self.userpass: 
 55              self.err = "Bad self.userpass data" 
 56              return False 
 57          for u, p in self.userpass: 
 58              if user == u and passwd == p: 
 59                  self.err = "" 
 60                  return True 
 61          self.err = "Invalid username or password" 
 62          return False 
   63   
 65      implements(IAuth) 
 66      """Implement authentication against an .htpasswd file.""" 
 67   
 68      file = "" 
 69      """Path to the .htpasswd file to use.""" 
 70   
 72          """C{file} is a path to an .htpasswd file.""" 
 73          assert os.path.exists(file) 
 74          self.file = file 
  75   
 77          """Authenticate C{user} and C{passwd} against an .htpasswd file""" 
 78          if not os.path.exists(self.file): 
 79              self.err = "No such file: " + self.file 
 80              return False 
 81           
 82           
 83          lines = [l.rstrip().split(':', 1) 
 84                   for l in file(self.file).readlines()] 
 85           
 86          lines = [l for l in lines if l[0] == user] 
 87          if not lines: 
 88              self.err = "Invalid user/passwd" 
 89              return False 
 90           
 91           
 92          hash = lines[0][1] 
 93          from crypt import crypt  
 94          res = hash == crypt(passwd, hash[0:2]) 
 95          if res: 
 96              self.err = "" 
 97          else: 
 98              self.err = "Invalid user/passwd" 
 99          return res 
  100   
102      pageTitle = "Authentication Failed" 
103   
104 -    def content(self, request, cxt): 
 105          template = request.site.buildbot_service.templates.get_template("authfail.html") 
106          return template.render(**cxt) 
  107