1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from twisted.internet import defer
17 from buildbot.status.web.auth import IAuth
18 from buildbot.status.web.session import SessionManager
19
20 COOKIE_KEY="BuildBotSession"
22 """Decide who can do what."""
23
24 knownActions = [
25
26
27 'gracefulShutdown',
28 'forceBuild',
29 'forceAllBuilds',
30 'pingBuilder',
31 'stopBuild',
32 'stopAllBuilds',
33 'cancelPendingBuild',
34 'stopChange',
35 'cleanShutdown',
36 'showUsersPage',
37 ]
38
39 - def __init__(self,
40 default_action=False,
41 auth=None,
42 useHttpHeader=False,
43 httpLoginUrl=False,
44 **kwargs):
45 self.auth = auth
46 if auth:
47 assert IAuth.providedBy(auth)
48
49 self.useHttpHeader = useHttpHeader
50 self.httpLoginUrl = httpLoginUrl
51
52 self.config = dict( (a, default_action) for a in self.knownActions )
53 for act in self.knownActions:
54 if act in kwargs:
55 self.config[act] = kwargs[act]
56 del kwargs[act]
57
58 self.sessions = SessionManager()
59 if kwargs:
60 raise ValueError("unknown authorization action(s) " + ", ".join(kwargs.keys()))
61
63 if COOKIE_KEY in request.received_cookies:
64 cookie = request.received_cookies[COOKIE_KEY]
65 return self.sessions.get(cookie)
66 return None
67
69 if self.useHttpHeader:
70 return request.getUser() != ''
71 return self.session(request) != None
72
79
81 """Get the userid of the user"""
82 if self.useHttpHeader:
83 return request.getUser()
84 s = self.session(request)
85 if s:
86 return s.user
87 return request.args.get("username", ["<unknown>"])[0]
88
90 """Get the user formatated in html (with possible link to email)"""
91 if self.useHttpHeader:
92 return request.getUser()
93 s = self.session(request)
94 if s:
95 return s.userInfosHTML()
96 return "not authenticated?!"
97
99 """Get the full username as fullname <email>"""
100 if self.useHttpHeader:
101 return request.getUser()
102 s = self.session(request)
103 if s:
104 return "%(fullName)s <%(email)s>"%(s.infos)
105 else:
106 return request.args.get("username", ["<unknown>"])[0]
107
108
110 if self.useHttpHeader:
111 return request.getPassword()
112 return request.args.get("passwd", ["<no-password>"])[0]
113
115 """Should the web interface even show the form for ACTION?"""
116 if action not in self.knownActions:
117 raise KeyError("unknown action")
118 cfg = self.config.get(action, False)
119 if cfg:
120 if cfg == 'auth' or callable(cfg):
121 return self.authenticated(request)
122 return cfg
123
125 """Is this ACTION allowed, given this http REQUEST?"""
126 if action not in self.knownActions:
127 raise KeyError("unknown action")
128 cfg = self.config.get(action, False)
129 if cfg:
130 if cfg == 'auth' or callable(cfg):
131 if not self.auth:
132 return defer.succeed(False)
133 def check_authenticate(res):
134 if callable(cfg) and not cfg(self.getUsername(request), *args):
135 return False
136 return True
137
138
139 passwd = self.getPassword(request)
140 if self.authenticated(request):
141 return defer.succeed(check_authenticate(None))
142 elif passwd != "<no-password>":
143 def check_login(cookie):
144 ret = False
145 if type(cookie) is str:
146 ret = check_authenticate(None)
147 self.sessions.remove(cookie)
148 return ret
149 d = self.login(request)
150 d.addBoth(check_login)
151 return d
152 else:
153 return defer.succeed(False)
154 return defer.succeed(cfg)
155
156 - def login(self, request):
157 """Login one user, and return session cookie"""
158 if self.authenticated(request):
159 return defer.succeed(False)
160
161 user = request.args.get("username", ["<unknown>"])[0]
162 passwd = request.args.get("passwd", ["<no-password>"])[0]
163 if user == "<unknown>" or passwd == "<no-password>":
164 return defer.succeed(False)
165 if not self.auth:
166 return defer.succeed(False)
167 d = defer.maybeDeferred(self.auth.authenticate, user, passwd)
168 def check_authenticate(res):
169 if res:
170 cookie, s = self.sessions.new(user, self.auth.getUserInfo(user))
171 request.addCookie(COOKIE_KEY, cookie, expires=s.getExpiration(),path="/")
172 request.received_cookies = {COOKIE_KEY:cookie}
173 return cookie
174 else:
175 return False
176 d.addBoth(check_authenticate)
177 return d
178
183