]>
Commit | Line | Data |
---|---|---|
dfff8bd5 MM |
1 | # vi: encoding=utf-8 ts=8 sts=4 sw=4 et |
2 | ||
1c54a525 | 3 | import sys |
308677c3 JR |
4 | if sys.version_info[0] == 2: |
5 | import ConfigParser | |
6 | else: | |
7 | import configparser as ConfigParser | |
57b6e61d | 8 | import string |
7906d44d | 9 | import fnmatch |
e3e3d74f | 10 | import os |
2f2bdae3 | 11 | import stat |
57b6e61d MM |
12 | |
13 | import path | |
14 | import log | |
bdc3292c | 15 | import status |
b5a39692 MM |
16 | from mailer import Message |
17 | from config import config | |
57b6e61d MM |
18 | |
19 | class User: | |
dfff8bd5 MM |
20 | def __init__(self, p, login): |
21 | self.login = login | |
22 | self.privs = [] | |
23 | self.gpg_emails = [] | |
24 | self.mailto = "" | |
cba0beaa | 25 | self.change_requester = False |
e6376553 | 26 | |
dfff8bd5 MM |
27 | if p.has_option(login, "gpg_emails"): |
28 | self.gpg_emails = string.split(p.get(login, "gpg_emails")) | |
29 | else: | |
30 | log.panic("acl: [%s] has no gpg_emails" % login) | |
e6376553 | 31 | |
dfff8bd5 MM |
32 | if p.has_option(login, "mailto"): |
33 | self.mailto = p.get(login, "mailto") | |
34 | else: | |
35 | if len(self.gpg_emails) > 0: | |
36 | self.mailto = self.gpg_emails[0] | |
e6376553 | 37 | |
cba0beaa KK |
38 | if p.has_option(login, "change_requester"): |
39 | self.change_requester = True | |
40 | ||
dfff8bd5 MM |
41 | if p.has_option(login, "privs"): |
42 | for p in string.split(p.get(login, "privs")): | |
43 | l = string.split(p, ":") | |
44 | if len(l) == 2: | |
45 | p+=":*" | |
46 | if len(l) not in (2,3) or l[0] == "" or l[1] == "": | |
47 | log.panic("acl: invalid priv format: '%s' [%s]" % (p, login)) | |
48 | else: | |
49 | self.privs.append(p) | |
57b6e61d | 50 | else: |
dfff8bd5 | 51 | log.panic("acl: [%s] has no privs" % login) |
57b6e61d | 52 | |
dfff8bd5 MM |
53 | def can_do(self, what, where, branch=None): |
54 | if branch: | |
55 | action = "%s:%s:%s" % (what, where, branch) | |
56 | else: | |
57 | action = "%s:%s:N-A" % (what, where) | |
58 | for priv in self.privs: | |
59 | if priv[0] == "!": | |
60 | ret = 0 | |
61 | priv = priv[1:] | |
62 | else: | |
63 | ret = 1 | |
64 | pwhat,pwhere,pbranch=priv.split(":") | |
65 | for pbranch in pbranch.split(","): | |
66 | priv="%s:%s:%s" % (pwhat,pwhere,pbranch) | |
67 | if fnmatch.fnmatch(action, priv): | |
68 | return ret | |
69 | return 0 | |
57b6e61d | 70 | |
dfff8bd5 MM |
71 | def check_priority(self, prio, where): |
72 | for priv in self.privs: | |
73 | val,builder=priv.split(":")[0:2] | |
74 | if fnmatch.fnmatch(where, builder): | |
75 | try: | |
76 | val=int(val) | |
77 | except ValueError: | |
78 | continue | |
79 | if prio>=val: | |
80 | return prio | |
81 | else: | |
82 | return val | |
dfff8bd5 | 83 | return prio |
60e340de | 84 | |
dfff8bd5 MM |
85 | def mail_to(self): |
86 | return self.mailto | |
57b6e61d | 87 | |
dfff8bd5 MM |
88 | def message_to(self): |
89 | m = Message() | |
90 | m.set_headers(to = self.mail_to(), cc = config.builder_list) | |
91 | return m | |
b5a39692 | 92 | |
dfff8bd5 MM |
93 | def get_login(self): |
94 | return self.login | |
57b6e61d | 95 | |
20b64239 | 96 | class ACL_Conf: |
dfff8bd5 | 97 | def __init__(self): |
e3e3d74f AM |
98 | self.reload() |
99 | ||
100 | def try_reload(self): | |
2f2bdae3 | 101 | mtime = os.stat(path.acl_conf)[stat.ST_MTIME] |
e3e3d74f AM |
102 | if mtime != self.acl_conf_mtime: |
103 | log.notice("acl.conf has changed, reloading...") | |
104 | self.reload() | |
e3e3d74f AM |
105 | return True |
106 | return False | |
107 | ||
108 | def reload(self): | |
0ff341f8 | 109 | self.acl_conf_mtime = os.stat(path.acl_conf)[stat.ST_MTIME] |
dfff8bd5 MM |
110 | self.current_user = None |
111 | status.push("reading acl.conf") | |
112 | p = ConfigParser.ConfigParser() | |
113 | p.readfp(open(path.acl_conf)) | |
114 | self.users = {} | |
115 | for login in p.sections(): | |
116 | if self.users.has_key(login): | |
117 | log.panic("acl: duplicate login: %s" % login) | |
118 | continue | |
119 | user = User(p, login) | |
120 | for e in user.gpg_emails: | |
121 | if self.users.has_key(e): | |
122 | log.panic("acl: user email colision %s <-> %s" % \ | |
123 | (self.users[e].login, login)) | |
124 | else: | |
125 | self.users[e] = user | |
126 | self.users[login] = user | |
127 | status.pop() | |
e6376553 | 128 | |
dfff8bd5 MM |
129 | def user_by_email(self, ems): |
130 | for e in ems: | |
131 | if self.users.has_key(e): | |
132 | return self.users[e] | |
133 | return None | |
57b6e61d | 134 | |
cba0beaa KK |
135 | def user_by_login(self, l): |
136 | return self.users[l] | |
137 | ||
dfff8bd5 MM |
138 | def user(self, l): |
139 | if not self.users.has_key(l): | |
140 | log.panic("no such user: %s" % l) | |
141 | return self.users[l] | |
2e33eed1 | 142 | |
dfff8bd5 MM |
143 | def set_current_user(self, u): |
144 | self.current_user = u | |
145 | if u != None: | |
146 | status.email = u.mail_to() | |
6b44a683 | 147 | |
dfff8bd5 MM |
148 | def current_user_login(self): |
149 | if self.current_user != None: | |
150 | return self.current_user.login | |
151 | else: | |
152 | return "" | |
6b44a683 | 153 | |
57b6e61d | 154 | acl = ACL_Conf() |