Package buildbot :: Package status :: Package web :: Module auth
[frames] | no frames]

Source Code for Module buildbot.status.web.auth

  1  # This file is part of Buildbot.  Buildbot is free software: you can 
  2  # redistribute it and/or modify it under the terms of the GNU General Public 
  3  # License as published by the Free Software Foundation, version 2. 
  4  # 
  5  # This program is distributed in the hope that it will be useful, but WITHOUT 
  6  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more 
  8  # details. 
  9  # 
 10  # You should have received a copy of the GNU General Public License along with 
 11  # this program; if not, write to the Free Software Foundation, Inc., 51 
 12  # Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 13  # 
 14  # Copyright Buildbot Team Members 
 15   
 16   
 17  import os 
 18  from zope.interface import Interface, implements 
 19  from buildbot.status.web.base import HtmlResource 
 20   
21 -class IAuth(Interface):
22 """Represent an authentication method.""" 23
24 - def authenticate(self, user, passwd):
25 """Check whether C{user} / C{passwd} are valid."""
26
27 - def errmsg(self):
28 """Get the reason authentication failed."""
29
30 -class AuthBase:
31 err = "" 32
33 - def errmsg(self):
34 return self.err
35
36 -class BasicAuth(AuthBase):
37 implements(IAuth) 38 """Implement basic authentication against a list of user/passwd.""" 39 40 userpass = [] 41 """List of user/pass tuples.""" 42
43 - def __init__(self, userpass):
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
52 - def authenticate(self, user, passwd):
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
64 -class HTPasswdAuth(AuthBase):
65 implements(IAuth) 66 """Implement authentication against an .htpasswd file.""" 67 68 file = "" 69 """Path to the .htpasswd file to use.""" 70
71 - def __init__(self, file):
72 """C{file} is a path to an .htpasswd file.""" 73 assert os.path.exists(file) 74 self.file = file
75
76 - def authenticate(self, user, passwd):
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 # Fetch each line from the .htpasswd file and split it into a 82 # [user, passwd] array. 83 lines = [l.rstrip().split(':', 1) 84 for l in file(self.file).readlines()] 85 # Keep only the line for this login 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 # This is the DES-hash of the password. The first two characters are 91 # the salt used to introduce disorder in the DES algorithm. 92 hash = lines[0][1] 93 from crypt import crypt #@UnresolvedImport 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
101 -class AuthFailResource(HtmlResource):
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