@@ -156,45 +156,47 @@ def __init__(self):
156
156
self .user = {}
157
157
self .result = {}
158
158
159
- def kaka2user (self , kaka ):
160
- logger .debug ("KAKA: %s" % kaka )
161
- if kaka :
162
- cookie_obj = SimpleCookie (kaka )
159
+ def get_user (self , environ ):
160
+ cookie = environ .get ("HTTP_COOKIE" , '' )
161
+
162
+ logger .debug ("Cookie: %s" % cookie )
163
+ if cookie :
164
+ cookie_obj = SimpleCookie (cookie )
163
165
morsel = cookie_obj .get (self .cookie_name , None )
164
166
if morsel :
165
167
try :
166
168
return self .uid2user [morsel .value ]
167
169
except KeyError :
168
170
return None
169
171
else :
170
- logger .debug ("No spauthn cookie" )
172
+ logger .debug ("No %s cookie" , self .cookie_name )
173
+
171
174
return None
172
175
173
- def delete_cookie (self , environ = None , kaka = None ):
174
- if not kaka :
175
- kaka = environ .get ("HTTP_COOKIE" , '' )
176
- logger .debug ("delete KAKA: %s" % kaka )
177
- if kaka :
176
+ def delete_cookie (self , environ ):
177
+ cookie = environ .get ("HTTP_COOKIE" , '' )
178
+ logger .debug ("delete cookie: %s" % cookie )
179
+ if cookie :
178
180
_name = self .cookie_name
179
- cookie_obj = SimpleCookie (kaka )
181
+ cookie_obj = SimpleCookie (cookie )
180
182
morsel = cookie_obj .get (_name , None )
181
183
cookie = SimpleCookie ()
182
184
cookie [_name ] = ""
183
185
cookie [_name ]['path' ] = "/"
184
186
logger .debug ("Expire: %s" % morsel )
185
- cookie [_name ]["expires" ] = _expiration ("dawn " )
186
- return tuple ( cookie .output ().split (": " , 1 ) )
187
+ cookie [_name ]["expires" ] = _expiration ("now " )
188
+ return cookie .output ().split (": " , 1 )
187
189
return None
188
190
189
- def user2kaka (self , user ):
191
+ def set_cookie (self , user ):
190
192
uid = rndstr (32 )
191
193
self .uid2user [uid ] = user
192
194
cookie = SimpleCookie ()
193
195
cookie [self .cookie_name ] = uid
194
196
cookie [self .cookie_name ]['path' ] = "/"
195
197
cookie [self .cookie_name ]["expires" ] = _expiration (480 )
196
198
logger .debug ("Cookie expires: %s" % cookie [self .cookie_name ]["expires" ])
197
- return tuple ( cookie .output ().split (": " , 1 ) )
199
+ return cookie .output ().split (": " , 1 )
198
200
199
201
200
202
# -----------------------------------------------------------------------------
@@ -318,6 +320,12 @@ def not_authn(self):
318
320
# -----------------------------------------------------------------------------
319
321
320
322
323
+ class User (object ):
324
+ def __init__ (self , name_id , data ):
325
+ self .name_id = name_id
326
+ self .data = data
327
+
328
+
321
329
class ACS (Service ):
322
330
def __init__ (self , sp , environ , start_response , cache = None , ** kwargs ):
323
331
Service .__init__ (self , environ , start_response )
@@ -357,7 +365,14 @@ def do(self, response, binding, relay_state="", mtype="response"):
357
365
return resp (self .environ , self .start_response )
358
366
359
367
logger .info ("AVA: %s" % self .response .ava )
360
- resp = Response (dict_to_table (self .response .ava ))
368
+
369
+ user = User (self .response .name_id , self .response .ava )
370
+ cookie = self .cache .set_cookie (user )
371
+
372
+ resp = Redirect ("/" , headers = [
373
+ ("Location" , "/" ),
374
+ cookie ,
375
+ ])
361
376
return resp (self .environ , self .start_response )
362
377
363
378
def verify_attributes (self , ava ):
@@ -543,7 +558,6 @@ def redirect_to_auth(self, _cli, entity_id, came_from):
543
558
ht_args = _cli .apply_binding (_binding , "%s" % req , destination ,
544
559
relay_state = _rstate )
545
560
_sid = req_id
546
- logger .debug ("ht_args: %s" % ht_args )
547
561
except Exception , exc :
548
562
logger .exception (exc )
549
563
resp = ServiceError (
@@ -582,6 +596,19 @@ def do(self):
582
596
# ----------------------------------------------------------------------------
583
597
584
598
599
+ class SLO (Service ):
600
+ def __init__ (self , sp , environ , start_response , cache = None ):
601
+ Service .__init__ (self , environ , start_response )
602
+ self .sp = sp
603
+ self .cache = cache
604
+
605
+ def do (self , response , binding , relay_state = "" , mtype = "response" ):
606
+ req_info = self .sp .parse_logout_request_response (response , binding )
607
+ return finish_logout (self .environ , self .start_response )
608
+
609
+ # ----------------------------------------------------------------------------
610
+
611
+
585
612
#noinspection PyUnusedLocal
586
613
def not_found (environ , start_response ):
587
614
"""Called if no URL matches."""
@@ -593,9 +620,18 @@ def not_found(environ, start_response):
593
620
594
621
595
622
#noinspection PyUnusedLocal
596
- def main (environ , start_response , _sp ):
597
- _sso = SSO (_sp , environ , start_response , cache = CACHE , ** ARGS )
598
- return _sso .do ()
623
+ def main (environ , start_response , sp ):
624
+ user = CACHE .get_user (environ )
625
+
626
+ if user is None :
627
+ sso = SSO (sp , environ , start_response , cache = CACHE , ** ARGS )
628
+ return sso .do ()
629
+
630
+ body = dict_to_table (user .data )
631
+ body += '<br><a href="/logout">logout</a>'
632
+
633
+ resp = Response (body )
634
+ return resp (environ , start_response )
599
635
600
636
601
637
def disco (environ , start_response , _sp ):
@@ -613,12 +649,67 @@ def disco(environ, start_response, _sp):
613
649
614
650
# ----------------------------------------------------------------------------
615
651
652
+
653
+ #noinspection PyUnusedLocal
654
+ def logout (environ , start_response , sp ):
655
+ user = CACHE .get_user (environ )
656
+
657
+ if user is None :
658
+ sso = SSO (sp , environ , start_response , cache = CACHE , ** ARGS )
659
+ return sso .do ()
660
+
661
+ logger .info ("[logout] subject_id: '%s'" % (user .name_id ,))
662
+
663
+ # What if more than one
664
+ data = sp .global_logout (user .name_id )
665
+ logger .info ("[logout] global_logout > %s" % data )
666
+
667
+ for entity_id , logout_info in data .items ():
668
+ if isinstance (logout_info , tuple ):
669
+ binding , http_info = logout_info
670
+
671
+ if binding == BINDING_HTTP_POST :
672
+ body = '' .join (http_info ['data' ])
673
+ resp = Response (body )
674
+ return resp (environ , start_response )
675
+ elif binding == BINDING_HTTP_REDIRECT :
676
+ for key , value in http_info ['headers' ]:
677
+ if key .lower () == 'location' :
678
+ resp = Redirect (value )
679
+ return resp (environ , start_response )
680
+
681
+ resp = ServiceError ('missing Location header' )
682
+ return resp (environ , start_response )
683
+ else :
684
+ resp = ServiceError ('unknown logout binding: %s' , binding )
685
+ return resp (environ , start_response )
686
+ else : # result from logout, should be OK
687
+ pass
688
+
689
+ return finish_logout (environ , start_response )
690
+
691
+
692
+ def finish_logout (environ , start_response ):
693
+ logger .info ("[logout done] environ: %s" % environ )
694
+ logger .info ("[logout done] remaining subjects: %s" % CACHE .uid2user .values ())
695
+
696
+ # remove cookie and stored info
697
+ cookie = CACHE .delete_cookie (environ )
698
+
699
+ resp = Response ('You are now logged out of this service' , headers = [
700
+ cookie ,
701
+ ])
702
+ return resp (environ , start_response )
703
+
704
+ # ----------------------------------------------------------------------------
705
+
616
706
# map urls to functions
617
707
urls = [
618
708
# Hmm, place holder, NOT used
619
709
('place' , ("holder" , None )),
620
710
(r'^$' , main ),
621
- (r'^disco' , disco )
711
+ (r'^disco' , disco ),
712
+ (r'^logout$' , logout ),
622
713
]
623
714
624
715
@@ -630,6 +721,13 @@ def add_urls():
630
721
urls .append (("%s/redirect$" % base , (ACS , "redirect" , SP )))
631
722
urls .append (("%s/redirect/(.*)$" % base , (ACS , "redirect" , SP )))
632
723
724
+ base = "slo"
725
+
726
+ urls .append (("%s/post$" % base , (SLO , "post" , SP )))
727
+ urls .append (("%s/post/(.*)$" % base , (SLO , "post" , SP )))
728
+ urls .append (("%s/redirect$" % base , (SLO , "redirect" , SP )))
729
+ urls .append (("%s/redirect/(.*)$" % base , (SLO , "redirect" , SP )))
730
+
633
731
# ----------------------------------------------------------------------------
634
732
635
733
0 commit comments