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, Attribute, implements
19 from buildbot.status.web.base import HtmlResource, ActionResource
20 from buildbot.status.web.base import path_to_authfail
21
22 from buildbot.process.users import users
23
25 """
26 Represent an authentication method.
27
28 Note that each IAuth instance contains a link to the BuildMaster that
29 will be set once the IAuth instance is initialized.
30 """
31
32 master = Attribute('master', "Link to BuildMaster, set when initialized")
33
35 """Check whether C{user} / C{passwd} are valid."""
36
38 """return dict with user info.
39 dict( fullName="", email="", groups=[])
40 """
41
43 """Get the reason authentication failed."""
44
55
57 implements(IAuth)
58 """Implement basic authentication against a list of user/passwd."""
59
60 userpass = []
61 """List of user/pass tuples."""
62
64 """C{userpass} is a list of (user, passwd)."""
65 for item in userpass:
66 assert isinstance(item, tuple) or isinstance(item, list)
67 u, p = item
68 assert isinstance(u, str)
69 assert isinstance(p, str)
70 self.userpass = userpass
71
73 """Check that C{user}/C{passwd} is a valid user/pass tuple."""
74 if not self.userpass:
75 self.err = "Bad self.userpass data"
76 return False
77 for u, p in self.userpass:
78 if user == u and passwd == p:
79 self.err = ""
80 return True
81 self.err = "Invalid username or password"
82 return False
83
85 implements(IAuth)
86 """Implement authentication against an .htpasswd file."""
87
88 file = ""
89 """Path to the .htpasswd file to use."""
90
92 """C{file} is a path to an .htpasswd file."""
93 assert os.path.exists(file)
94 self.file = file
95
97 """Authenticate C{user} and C{passwd} against an .htpasswd file"""
98 if not os.path.exists(self.file):
99 self.err = "No such file: " + self.file
100 return False
101
102
103 lines = [l.rstrip().split(':', 1)
104 for l in file(self.file).readlines()]
105
106 lines = [l for l in lines if l[0] == user]
107 if not lines:
108 self.err = "Invalid user/passwd"
109 return False
110 hash = lines[0][1]
111 res = self.validatePassword(passwd, hash)
112 if res:
113 self.err = ""
114 else:
115 self.err = "Invalid user/passwd"
116 return res
117
119
120
121 from crypt import crypt
122 return hash == crypt(passwd, hash[0:2])
123
124
126 implements(IAuth)
127 """Implement authentication against an .htpasswd file based on libaprutil"""
128
129 file = ""
130 """Path to the .htpasswd file to use."""
131
133 HTPasswdAuth.__init__(self, file)
134
135
136 self.apr = None
137 try:
138 from ctypes import CDLL
139 from ctypes.util import find_library
140 lib = find_library("aprutil-1")
141 if lib:
142 self.apr = CDLL(lib)
143 except:
144 self.apr = None
145
147
148
149 if self.apr:
150 return self.apr.apr_password_validate(passwd, hash) == 0
151 else:
152 return HTPasswdAuth.validatePassword(self, passwd, hash)
153
155 """Implement authentication against users in database"""
156 implements(IAuth)
157
159 """
160 It checks for a matching uid in the database for the credentials
161 and return True if a match is found, False otherwise.
162
163 @param user: username portion of user credentials
164 @type user: string
165
166 @param passwd: password portion of user credentials
167 @type passwd: string
168
169 @returns: boolean via deferred.
170 """
171 d = self.master.db.users.getUserByUsername(user)
172 def check_creds(user):
173 if user:
174 if users.check_passwd(passwd, user['bb_password']):
175 return True
176 self.err = "no user found with those credentials"
177 return False
178 d.addCallback(check_creds)
179 return d
180
182 pageTitle = "Authentication Failed"
183
184 - def content(self, request, cxt):
185 templates =request.site.buildbot_service.templates
186 template = templates.get_template("authfail.html")
187 return template.render(**cxt)
188
190 pageTitle = "Authorization Failed"
191
192 - def content(self, request, cxt):
193 templates =request.site.buildbot_service.templates
194 template = templates.get_template("authzfail.html")
195 return template.render(**cxt)
196
198
210 d.addBoth(on_login)
211 return d
212
221