Changeset 78f2668 for fedd/federation/access.py
- Timestamp:
- Nov 30, 2010 10:48:51 AM (13 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master
- Children:
- 822d31b
- Parents:
- 027b87b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/federation/access.py
r027b87b r78f2668 124 124 125 125 126 def read_access(self, config, access_obj=None): 127 """ 128 Read an access DB with filename config of the form: 129 (id, id, id) -> attribute, something 130 where the ids can be fedids, strings, or <any> or <none>, attribute is 131 the attribute to assign , and something is any set of charcters. The 132 hash self.access is populated with mappings from those triples to the 133 results of access_obj being called on the remainder of the line (if 134 present). If access_obj is not given, the string itself is entered in 135 the hash. Additionally, a triple with <any> and <none> mapped to None 136 is entered in self.auth with the attribute given. 137 138 Parsing errors result in a self.parse_error exception being raised. 139 access_obj should throw that as well. 140 """ 141 lineno=0 142 name_expr = "["+string.ascii_letters + string.digits + "\.\-_]+" 143 fedid_expr = "fedid:[" + string.hexdigits + "]+" 144 key_name = "(<ANY>|<NONE>|"+fedid_expr + "|"+ name_expr + ")" 145 access_re = re.compile('\('+key_name+'\s*,\s*'+key_name+'\s*,\s*'+ 146 key_name+'\s*\)\s*->\s*([^,]+)\s*(.*)', re.IGNORECASE) 147 148 def parse_name(n): 149 if n.startswith('fedid:'): return fedid(hexstr=n[len('fedid:'):]) 150 else: return n 151 152 def auth_name(n): 153 if isinstance(n, basestring): 154 if n =='<any>' or n =='<none>': return None 155 else: return unicode(n) 156 else: 157 return n 158 def strip_comma(s): 159 s = s.strip() 160 if s.startswith(','): 161 s = s[1:].strip() 162 return s 163 164 if access_obj is None: 165 access_obj = lambda(x): "%s" % x 166 167 f = open(config, "r"); 168 try: 169 for line in f: 170 lineno += 1 171 line = line.strip(); 172 if len(line) == 0 or line.startswith('#'): 173 continue 174 175 # Access line (t, p, u) -> anything 176 m = access_re.match(line) 177 if m != None: 178 access_key = tuple([ parse_name(x) \ 179 for x in m.group(1,2,3)]) 180 attribute = m.group(4) 181 auth_key = tuple([ auth_name(x) for x in access_key]) 182 self.auth.set_attribute(auth_key, attribute) 183 if len(m.group(5)) > 0: 184 access_val = access_obj(strip_comma(m.group(5))) 185 self.access[access_key] = access_val 186 continue 187 188 # Nothing matched to here: unknown line - raise exception 189 f.close() 190 raise self.parse_error( 191 "Unknown statement at line %d of %s" % \ 192 (lineno, config)) 193 finally: 194 if f: f.close() 195 196 def read_abac_access(self, fn, access_obj=None): 126 def read_access(self, fn, access_obj=None): 197 127 """ 198 128 Read an access DB of the form … … 228 158 finally: 229 159 if f: f.close() 230 231 232 def get_users(self, obj):233 """234 Return a list of the IDs of the users in dict235 """236 if obj.has_key('user'):237 return [ unpack_id(u['userID']) \238 for u in obj['user'] if u.has_key('userID') ]239 else:240 return None241 160 242 161 def write_state(self): … … 279 198 280 199 281 282 def permute_wildcards(self, a, p):283 """Return a copy of a with various fields wildcarded.284 285 The bits of p control the wildcards. A set bit is a wildcard286 replacement with the lowest bit being user then project then testbed.287 """288 if p & 1: user = ["<any>"]289 else: user = a[2]290 if p & 2: proj = "<any>"291 else: proj = a[1]292 if p & 4: tb = "<any>"293 else: tb = a[0]294 295 return (tb, proj, user)296 297 def find_access(self, search):298 """299 Search the access DB for a match on this tuple. Return the matching300 access tuple and the user that matched.301 302 NB, if the initial tuple fails to match we start inserting wildcards in303 an order determined by self.project_priority. Try the list of users in304 order (when wildcarded, there's only one user in the list).305 """306 if self.project_priority: perm = (0, 1, 2, 3, 4, 5, 6, 7)307 else: perm = (0, 2, 1, 3, 4, 6, 5, 7)308 309 for p in perm:310 s = self.permute_wildcards(search, p)311 # s[2] is None on an anonymous, unwildcarded request312 if s[2] != None:313 for u in s[2]:314 if self.access.has_key((s[0], s[1], u)):315 return (self.access[(s[0], s[1], u)], u)316 else:317 if self.access.has_key(s):318 return (self.access[s], None)319 return None, None320 321 def lookup_access_base(self, req, fid):322 """323 Determine the allowed access for this request. Return the access and324 which fields are dynamic.325 326 The fedid is needed to construct the request327 """328 user_re = re.compile("user:\s(.*)")329 project_re = re.compile("project:\s(.*)")330 331 # Search keys332 tb = fid333 user = [ user_re.findall(x)[0] for x in req.get('credential', []) \334 if user_re.match(x)]335 project = [ project_re.findall(x)[0] \336 for x in req.get('credential', []) \337 if project_re.match(x)]338 339 if len(project) == 1: project = project[0]340 elif len(project) == 0: project = None341 else:342 raise service_error(service_error.req,343 "More than one project credential")344 345 # Confirm authorization346 for u in user:347 self.log.debug("[lookup_access] Checking access for %s" % \348 ((tb, project, u),))349 if self.auth.check_attribute((tb, project, u), 'access'):350 self.log.debug("[lookup_access] Access granted")351 break352 else:353 self.log.debug("[lookup_access] Access Denied")354 else:355 raise service_error(service_error.access, "Access denied")356 357 # This maps a valid user to the Emulab projects and users to use358 found, user_match = self.find_access((tb, project, user))359 360 return (found, (tb, project, user_match))361 362 363 200 def get_handler(self, path, fid): 201 """ 202 This function is somewhat oddly named. It doesn't get a handler, it 203 handles GETs. Specifically, it handls https GETs for retrieving data 204 from the repository exported by the access server. 205 """ 364 206 self.log.info("Get handler %s %s" % (path, fid)) 365 207 if self.auth.check_attribute(fid, path) and self.userconfdir:
Note: See TracChangeset
for help on using the changeset viewer.