Changeset 1098 for trunk/rp/trac
- Timestamp:
- 11/16/07 14:18:30 (14 months ago)
- Location:
- trunk/rp/trac
- Files:
-
- 2 added
- 6 modified
-
infocard_acct.tar (modified) (previous)
-
infocard_acct/0.11/infocard_acct/groups.py (added)
-
infocard_acct/0.11/infocard_acct/infocard/infocardlib.py (modified) (11 diffs)
-
infocard_acct/0.11/infocard_acct/ldapstore.py (modified) (2 diffs)
-
infocard_acct/0.11/infocard_acct/templates/infocard-detail.html (modified) (2 diffs)
-
infocard_acct/0.11/infocard_acct/templates/infocard-session-detail.html (added)
-
infocard_acct/0.11/infocard_acct/web_ui.py (modified) (13 diffs)
-
infocard_acct/0.11/setup.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/rp/trac/infocard_acct/0.11/infocard_acct/infocard/infocardlib.py
r1061 r1098 63 63 import xmlseclibs, cookielib, datetime 64 64 import hashlib 65 import urlparse 65 66 from xml.dom import minidom 66 67 from xml import xpath … … 227 228 else: 228 229 #do validity checking 229 self.isValid = self._isValid( )230 self.isValid = self._isValid(options) 230 231 #grab assertions/claims 231 self. assertions = self._getAssertions()232 self._setupAssertions(options) 232 233 #set up metadata about the token for later use 233 self._ getMiscData()234 self._setupMiscData(options) 234 235 else: 235 236 self.eventLog.add_event('Unable to decrypt token', … … 247 248 """Setup all of the data about the token we can 248 249 """ 249 def _ getMiscData(self):250 def _setupMiscData(self, options): 250 251 rootNode = self.decrypted.documentElement 251 252 if rootNode: … … 255 256 self.metadata[META_MajorVersion] = rootNode.getAttribute('MajorVersion') 256 257 self.metadata[META_MinorVersion] = rootNode.getAttribute('MinorVersion') 257 self.metadata[META_CardKeyHash] = self. getCardKeyHash()258 259 def _isValid(self ):258 self.metadata[META_CardKeyHash] = self._getCardKeyHash() 259 260 def _isValid(self, options): 260 261 """ Validate the SAML token 261 262 """ … … 266 267 self.eventLog.add_event("SAML Signature Location Failed", 267 268 event.ERROR, 'locate-saml-signature') 268 269 269 270 # Canonicalize the signed info 270 271 objXMLSecDSig.canonicalizeSignedInfo() … … 297 298 event.ERROR, 'verify-signature') 298 299 return False 299 300 300 301 #validate Conditions, both Audience and Time 301 302 xPath = xpath.CreateContext(self.decrypted) 302 303 xPath.setNamespaces({'mysaml' : SAML_1_0_ASSERT_NS}) 303 304 304 305 query = '/mysaml:Assertion/mysaml:Conditions/mysaml:AudienceRestrictionCondition/mysaml:Audience' 305 306 nodelist = xpath.Evaluate(query, context=xPath) … … 313 314 self.metadata[META_NotBefore] = node.getAttribute('NotBefore') 314 315 self.metadata[META_NotOnOrAfter] = node.getAttribute('NotOnOrAfter') 315 316 316 317 if ((not self.metadata[META_NotBefore]) or 317 318 (not self.metadata[META_NotOnOrAfter])): … … 330 331 if self.eventLog.has_severity(event.ERROR): 331 332 return False 332 333 333 334 return True 334 335 335 336 336 337 #TODO handle namespaces, claim name mapping, multiple values! 337 def _ getAssertions(self):338 def _setupAssertions(self, options): 338 339 if not self.assertions or len(self.assertions) == 0: 340 mvClaims = [] 341 temp = self._option(options, OPTION_multivalued_claims) 342 if temp: 343 mvClaims = temp.rsplit(' ') 339 344 xPath = xpath.CreateContext(self.decrypted) 340 345 xPath.setNamespaces({'mysaml' : SAML_1_0_ASSERT_NS}) 341 346 query = '/mysaml:Assertion/mysaml:AttributeStatement/mysaml:Attribute' 342 347 nodelist = xpath.Evaluate(query, context=xPath) 343 348 344 349 for node in nodelist: 350 ns = node.getAttribute('AttributeNamespace') 345 351 name = node.getAttribute('AttributeName') 346 352 if (name): … … 349 355 if (child.localName == 'AttributeValue'): 350 356 value = child.firstChild.data 351 break 352 self.assertions[name] = value 353 return self.assertions 354 355 def getCardKeyHash(self): 357 try: 358 nsDict = self.assertions[ns] 359 try: 360 if nsDict[name]: 361 #TODO multivalued check 362 pass 363 else: 364 nsDict[name] = value 365 except Exception: 366 nsDict[name] = value 367 except Exception: 368 self.assertions[ns] = {name:value} 369 370 def getAssertion(self, identifier=None): 371 """Allows retrivial of any claim or assertion associated with the security token 372 Returns either the data or None 373 visit and finish this function! 374 """ 375 #is the identifier a URI or just a short name? 376 ns = None 377 claim =None 378 try: 379 s = identifier.rsplit('/', 1) 380 if s.items() > 1: 381 ns = s[0] 382 claim = s[-1] 383 except Exception: 384 claim = identifier 385 386 claims = dict() 387 for nsElem in self.assertions.keys(): 388 if not ns or (ns and ns == nsElem): 389 nsDict = self.assertions[nsElem] 390 for key in nsDict.keys(): 391 if claim and claim == key: 392 return nsDict[key] 393 elif not claim: 394 if ns: 395 claims[ns+'//'+key] = nsDict[key] 396 else: 397 claims[key] = nsDict[key] 398 break 399 if claims.items(): 400 return claims 401 else: 402 return None 403 404 405 def getMetaData(self, identifier=None): 406 """Allows retrivial of any meta data associated with the security token 407 Pass a specific string for the identifier and receive either a 408 string or None 409 If the identifier is None then a dictionary of all meta data is returned 410 Currently all meta data is single valued! 411 """ 412 if identifier: 413 try: 414 return self.metadata[identifier] 415 except Exception: 416 return None 417 else: 418 return self.metadata 419 420 def _getCardKeyHash(self): 356 421 try: 357 422 return self.metadata[META_CardKeyHash] … … 359 424 m = hashlib.md5() 360 425 signer = None 361 if 'privatepersonalidentifier' in self.assertions: 362 m.update(self.assertions['privatepersonalidentifier']) 426 ppid = self.getAssertion('privatepersonalidentifier') 427 if ppid: 428 m.update(ppid) 363 429 if self.objKeyInfo and self.objKeyInfo.isEncrypted: 364 430 if self.objKeyInfo.modulus: … … 366 432 if self.objKeyInfo.exponent: 367 433 m.update(self.objKeyInfo.exponent) 368 # if self.objKeyInfo.encryptedCtx:369 # m.update(self.objKeyInfo.encryptedCtx)370 434 self.metadata[META_CardKeyHash] = m.hexdigest() 371 435 return self.metadata[META_CardKeyHash] -
trunk/rp/trac/infocard_acct/0.11/infocard_acct/ldapstore.py
r1061 r1098 130 130 # if self._user_is_invalid(user): 131 131 # return False 132 #try:132 try: 133 133 search_url = self._setup_search_url() 134 134 if search_url: … … 136 136 l.simple_bind_s(search_url.who, search_url.cred) 137 137 searchfilter = '(& ' + search_url.filterstr + '('+ self._get_attr(search_url)+'='+ user +'))' 138 self.log.debug('LDAPUserStore:check_password: searching \"%s\" '139 + 'for \"%s\"', search_url.dn, searchfilter)138 # self.log.debug('LDAPUserStore:check_password: searching \"%s\" ' 139 # + 'for \"%s\"', search_url.dn, searchfilter) 140 140 results = l.search_s(search_url.dn, search_url.scope, searchfilter) 141 141 if len(results) == 1: 142 self.log.debug('LDAPUserStore:check_password \"%s\" for \"%s\"',143 password, (results[0])[0])144 for entry in results:145 self.log.debug('LDAPUserStore:check_password \"%s\"', entry[0])146 self.log.debug('LDAPUserStore:check_password \"%s\"', entry[1])142 # self.log.debug('LDAPUserStore:check_password \"%s\" for \"%s\"', 143 # password, (results[0])[0]) 144 # for entry in results: 145 # self.log.debug('LDAPUserStore:check_password \"%s\"', entry[0]) 146 # self.log.debug('LDAPUserStore:check_password \"%s\"', entry[1]) 147 147 l.simple_bind_s(results[0][0], password) 148 self.log.debug('LDAPUserStore:check_password succeeded')148 # self.log.debug('LDAPUserStore:check_password succeeded') 149 149 return True 150 elif len(results) == 0:151 self.log.debug('LDAPUserStore:check_password search failed')152 else:153 for entry in results:154 self.log.debug('LDAPUserStore:check_password \"%s\"', entry[0])155 self.log.debug('LDAPUserStore:check_password \"%s\"', entry[1])156 #except:150 # elif len(results) == 0: 151 # self.log.debug('LDAPUserStore:check_password search failed') 152 # else: 153 # for entry in results: 154 # self.log.debug('LDAPUserStore:check_password \"%s\"', entry[0]) 155 # self.log.debug('LDAPUserStore:check_password \"%s\"', entry[1]) 156 except: 157 157 #on error just return the password failed 158 # nop=1159 158 self.log.debug('LDAPUserStore:check_password failed') 160 159 return False -
trunk/rp/trac/infocard_acct/0.11/infocard_acct/templates/infocard-detail.html
r1061 r1098 69 69 </table> 70 70 71 <table py:if="infocard.assertions" class="listing" id="claims"> 71 <py:with vars="claims =infocard.getAssertion()"> 72 <table py:if="claims" class="listing" id="claims"> 72 73 <thead> 73 74 <tr> … … 76 77 </thead> 77 78 <tbody> 78 <div py:for="name in infocard.assertions.keys()">79 <div py:for="name in claims.keys()"> 79 80 <tr> 80 81 <td><pre>${name}</pre></td> 81 <td><pre>${ infocard.assertions[name]}</pre></td>82 <td><pre>${claims[name]}</pre></td> 82 83 </tr> 83 84 </div> 84 85 </tbody> 85 86 </table> 86 87 </py:with> 87 88 88 89 </body> -
trunk/rp/trac/infocard_acct/0.11/infocard_acct/web_ui.py
r1061 r1098 48 48 49 49 from acct_mgr.api import AccountManager 50 from acct_mgr import web_ui 50 51 from acct_mgr.web_ui import AccountModule 51 52 52 53 from association import AssociationManager 53 54 54 #for infocard functions55 55 import infocard.xmlseclibs, infocard.infocardlib 56 from infocard import infocardlib 56 57 from infocard.infocardlib import SecToken, InfoCardProcessor 57 58 … … 81 82 privacyPolicyVer = Option('infocard_acct', 'privacy_version', '') 82 83 issuer = Option('infocard_acct', 'privacy_issuer', '') 83 displayDebug = BoolOption('infocard_acct', 'debug', False)84 84 85 85 self.privateKey = self.env.config['infocard_acct'].get('private_key_path') … … 89 89 self.privacyPolicyVer = self.env.config['infocard_acct'].get('privacy_version') 90 90 self.issuer = self.env.config['infocard_acct'].get('issuer') 91 self.displayDebug = self. env.config['infocard_acct'].get('debug')91 self.displayDebug = self.config.getbool('infocard_acct', 'debug', False) 92 92 93 93 #append all hard coded mandatory claims to the required claims … … 115 115 authenticate = if_enabled(authenticate) 116 116 117 match_request = if_enabled(auth.LoginModule.match_request) 117 def match_request(self, req): 118 if if_enabled(auth.LoginModule.match_request) \ 119 and ( (re.match(r'/login/?$', req.path_info) is not None) \ 120 or (re.match(r'/logout/?$', req.path_info) is not None)): 121 return True 122 123 if re.match(r'/iinfo/?$', req.path_info) is not None: 124 return True 125 126 return False 118 127 119 128 def process_request(self, req): 120 #self.log.debug('web_ui:LoginModule:process_request : %s for %s', req.path_info, req.authname ) 129 # self.log.debug('web_ui:LoginModule:process_request : '+req.path_info) 130 if req.path_info.startswith('/logout'): 131 self._cleanup_session(req) 132 if req.path_info.startswith('/iinfo'): 133 data = { 134 'title': 'Infocard Session Debug', 135 'session': req.session, 136 'tok_claims': req.session.get('tok_claims'), 137 'tok_meta': req.session.get('tok_meta') 138 } 139 return 'infocard-session-detail.html', data, None 121 140 if req.path_info.startswith('/login'): 122 141 if req.authname == 'anonymous': … … 146 165 elif secToken: 147 166 if secToken and secToken.isValid: 148 cardkeyhash = secToken.getCardKeyHash() 167 cardkeyhash = secToken.getMetaData(infocard.infocardlib.META_CardKeyHash) 168 self._setup_session(req) 149 169 elif secToken: 150 170 #invalid security token, handle error … … 165 185 elif req.args.get('xmlToken') and self.displayDebug: 166 186 self._do_debug_login(req) 187 self._setup_session(req) 167 188 secToken = self._get_token(req) 168 189 data = { … … 173 194 data['events'] = secToken.eventLog.events 174 195 return 'infocard-detail.html', data, None 196 175 197 self.log.debug("%s", self.displayDebug) 198 self._setup_session(req) 176 199 return auth.LoginModule.process_request(self, req) 177 200 201 def _cleanup_session(self, req): 202 """We need to delete session attributes here 203 """ 204 pass 205 206 def _setup_session(self, req): 207 """setup session with infocard variables so we can get back to them 208 the infocard must be parsed and availible on this request 209 """ 210 secToken = self._get_token(req) 211 if secToken: 212 metaData = secToken.getMetaData() 213 if metaData: 214 tok_meta='' 215 for key in metaData.keys(): 216 req.session['tok_meta_'+key] = metaData[key] 217 tok_meta += ' tok_meta_'+key 218 req.session['tok_meta'] = tok_meta 219 #self.log.debug("tok_meta : %s", tok_meta) 220 claims = secToken.getAssertion() 221 if claims and claims.keys(): 222 tok_claims='' 223 for key in claims.keys(): 224 req.session['tok_claim_'+key] = claims[key] 225 tok_claims += ' tok_claim_'+key 226 req.session['tok_claims'] = tok_claims 227 #self.log.debug("tok_claims : %s", tok_claims) 228 178 229 def _do_debug_login(self, req): 179 230 """this emulates the code in trac.web.auth.py, but doesn't do the redirect 231 It should be only used for the debug login. 180 232 """ 181 233 ignore_case = BoolOption('trac', 'ignore_auth_case', 'false', 182 234 """Whether case should be ignored for login names (''since 0.9'').""") 235 183 236 remote_user = req.remote_user 184 237 if self.ignore_case: … … 196 249 req.outcookie['trac_auth']['path'] = req.href() 197 250 198 # Manage the singletons for proecessors199 251 def _get_processor(self, req): 252 """Manage the singletons for proecessors 253 """ 200 254 processor = None 201 255 processorTag = req.args.get('blockID') … … 214 268 215 269 216 # get the security token, cache it on the request so it isn't reparsed217 270 def _get_token(self, req): 271 """get the security token, cache it on the request so it isn't reparsed 272 """ 273 218 274 secToken = None 219 275 try: … … 253 309 secToken = self._get_token(req) 254 310 if secToken and secToken.isValid: 255 user = AssociationManager(self.env).check_association(secToken.get CardKeyHash())311 user = AssociationManager(self.env).check_association(secToken.getMetaData(infocard.infocardlib.META_CardKeyHash)) 256 312 if user: 257 313 #self.log.debug('web_user:LoginModule:_remote_user:check_association returned : \"%s\"', user) … … 275 331 def enabled(self): 276 332 # Users should disable the built-in authentication to use this one 277 return not self.env.is_component_enabled(auth.LoginModule) 333 return not (self.env.is_component_enabled(auth.LoginModule) \ 334 or self.env.is_component_enabled(web_ui.LoginModule)) 278 335 enabled = property(enabled) 279 336 … … 285 342 """ 286 343 from pkg_resources import resource_filename 287 self.log.debug('LoginModule:get_htdocs_dirs: %s', resource_filename(__name__, 'htdocs'))344 # self.log.debug('LoginModule:get_htdocs_dirs: %s', resource_filename(__name__, 'htdocs')) 288 345 return [('infocard_acct', resource_filename(__name__, 'htdocs')), 289 346 ('site', self.env.get_htdocs_dir())] … … 294 351 """ 295 352 from pkg_resources import resource_filename 296 self.log.debug('LoginModule:get_templates_dirs: %s', resource_filename(__name__, 'templates'))353 # self.log.debug('LoginModule:get_templates_dirs: %s', resource_filename(__name__, 'templates')) 297 354 return [resource_filename(__name__, 'templates')] 298 355 -
trunk/rp/trac/infocard_acct/0.11/setup.py
r1061 r1098 143 143 infocard_acct.ldapstore = infocard_acct.ldapstore 144 144 infocard_acct.web_ui = infocard_acct.web_ui 145 infocard_acct.groups = infocard_acct.groups 145 146 """, 146 147