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