11#!/usr/bin/env python 
22from  __future__ import  print_function 
3- import  logging 
4- import  re 
3+ 
54import  argparse 
5+ import  importlib 
6+ import  logging 
67import  os 
8+ import  re 
9+ import  sys 
710
8- from  six .moves .http_cookies  import  SimpleCookie 
911import  six 
10- 
11- from  saml2 .extension .pefim  import  SPCertEnc 
12- from  saml2 .metadata  import  create_metadata_string 
13- import  service_conf 
14- 
12+ from  six .moves .http_cookies  import  SimpleCookie 
1513from  six .moves .urllib .parse  import  parse_qs 
16- import  sys 
1714
15+ import  saml2 .xmldsig  as  ds 
16+ from  saml2  import  BINDING_HTTP_ARTIFACT 
17+ from  saml2  import  BINDING_HTTP_POST 
1818from  saml2  import  BINDING_HTTP_REDIRECT , element_to_extension_element 
1919from  saml2  import  BINDING_SOAP 
20- from  saml2  import  time_util 
2120from  saml2  import  ecp 
22- from  saml2  import  BINDING_HTTP_ARTIFACT 
23- from  saml2  import  BINDING_HTTP_POST 
21+ from  saml2  import  time_util 
2422from  saml2 .client  import  Saml2Client 
2523from  saml2 .ecp_client  import  PAOS_HEADER_INFO 
26- from  saml2 .httputil  import  geturl , make_cookie , parse_cookie 
27- from  saml2 .httputil  import  get_post 
28- from  saml2 .httputil  import  Response 
24+ from  saml2 .extension .pefim  import  SPCertEnc 
2925from  saml2 .httputil  import  BadRequest 
30- from  saml2 .httputil  import  ServiceError 
31- from  saml2 .httputil  import  SeeOther 
32- from  saml2 .httputil  import  Unauthorized 
3326from  saml2 .httputil  import  NotFound 
34- from  saml2 .httputil  import  Redirect 
3527from  saml2 .httputil  import  NotImplemented 
28+ from  saml2 .httputil  import  Redirect 
29+ from  saml2 .httputil  import  Response 
30+ from  saml2 .httputil  import  SeeOther 
31+ from  saml2 .httputil  import  ServiceError 
32+ from  saml2 .httputil  import  Unauthorized 
33+ from  saml2 .httputil  import  get_post 
34+ from  saml2 .httputil  import  geturl , make_cookie , parse_cookie 
35+ from  saml2 .metadata  import  create_metadata_string 
3636from  saml2 .response  import  StatusError 
3737from  saml2 .response  import  VerificationError 
3838from  saml2 .s_utils  import  UnknownPrincipal 
39- from  saml2 .s_utils  import  decode_base64_and_inflate 
4039from  saml2 .s_utils  import  UnsupportedBinding 
41- from  saml2 .s_utils  import  sid 
40+ from  saml2 .s_utils  import  decode_base64_and_inflate 
4241from  saml2 .s_utils  import  rndstr 
43- #from srtest import exception_trace 
42+ from  saml2 .s_utils  import  sid 
43+ from  saml2 .saml  import  NAMEID_FORMAT_PERSISTENT 
4444from  saml2 .samlp  import  Extensions 
45- from  saml2  import  xmldsig  as  ds 
46- import  saml2 .xmldsig  as  ds 
4745
4846logger  =  logging .getLogger ("" )
4947hdlr  =  logging .FileHandler ('spx.log' )
5452logger .addHandler (hdlr )
5553logger .setLevel (logging .INFO )
5654
57- 
5855SP  =  None 
5956SEED  =  "" 
6057POLICY  =  None 
@@ -139,7 +136,7 @@ class ECPResponse(object):
139136    def  __init__ (self , content ):
140137        self .content  =  content 
141138
142-     #noinspection PyUnusedLocal 
139+     #  noinspection PyUnusedLocal 
143140    def  __call__ (self , environ , start_response ):
144141        start_response ('%s %s'  %  (self .code , self .title ),
145142                       [('Content-Type' , "text/xml" )])
@@ -351,7 +348,7 @@ def do(self, response, binding, relay_state="", mtype="response"):
351348        :param response: The SAML response, transport encoded 
352349        :param binding: Which binding the query came in over 
353350        """ 
354-         #tmp_outstanding_queries = dict(self.outstanding_queries) 
351+         #  tmp_outstanding_queries = dict(self.outstanding_queries) 
355352        if  not  response :
356353            logger .info ("Missing Response" )
357354            resp  =  Unauthorized ('Unknown user' )
@@ -405,6 +402,7 @@ def verify_attributes(self, ava):
405402
406403        return  res 
407404
405+ 
408406# ----------------------------------------------------------------------------- 
409407# REQUESTERS 
410408# ----------------------------------------------------------------------------- 
@@ -554,7 +552,7 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
554552                "single_sign_on_service" , self .bindings , "idpsso" ,
555553                entity_id = entity_id )
556554            logger .debug ("binding: %s, destination: %s" , _binding ,
557-                                                             destination )
555+                          destination )
558556            # Binding here is the response binding that is which binding the 
559557            # IDP should use to return the response. 
560558            acs  =  _cli .config .getattr ("endpoints" , "sp" )[
@@ -565,19 +563,20 @@ def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
565563            extensions  =  None 
566564            cert  =  None 
567565            if  _cli .config .generate_cert_func  is  not None :
568-                      cert_str , req_key_str  =  _cli .config .generate_cert_func ()
569-                      cert  =  {
570-                          "cert" : cert_str ,
571-                          "key" : req_key_str 
572-                      }
573-                      spcertenc  =  SPCertEnc (x509_data = ds .X509Data (
574-                          x509_certificate = ds .X509Certificate (text = cert_str )))
575-                      extensions  =  Extensions (extension_elements = [
576-                          element_to_extension_element (spcertenc )])
566+                 cert_str , req_key_str  =  _cli .config .generate_cert_func ()
567+                 cert  =  {
568+                     "cert" : cert_str ,
569+                     "key" : req_key_str 
570+                 }
571+                 spcertenc  =  SPCertEnc (x509_data = ds .X509Data (
572+                     x509_certificate = ds .X509Certificate (text = cert_str )))
573+                 extensions  =  Extensions (extension_elements = [
574+                     element_to_extension_element (spcertenc )])
577575
578576            req_id , req  =  _cli .create_authn_request (destination ,
579577                                                    binding = return_binding ,
580-                                                     extensions = extensions )
578+                                                     extensions = extensions ,
579+                                                     nameid_format = NAMEID_FORMAT_PERSISTENT )
581580            _rstate  =  rndstr ()
582581            self .cache .relay_state [_rstate ] =  came_from 
583582            ht_args  =  _cli .apply_binding (_binding , "%s"  %  req , destination ,
@@ -636,7 +635,7 @@ def do(self, message, binding, relay_state="", mtype="response"):
636635        try :
637636            txt  =  decode_base64_and_inflate (message )
638637            is_logout_request  =  'LogoutRequest'  in  txt .split ('>' , 1 )[0 ]
639-         except :    # TODO: parse the XML correctly 
638+         except :  # TODO: parse the XML correctly 
640639            is_logout_request  =  False 
641640
642641        if  is_logout_request :
@@ -646,10 +645,11 @@ def do(self, message, binding, relay_state="", mtype="response"):
646645
647646        return  finish_logout (self .environ , self .start_response )
648647
648+ 
649649# ---------------------------------------------------------------------------- 
650650
651651
652- #noinspection PyUnusedLocal 
652+ #  noinspection PyUnusedLocal 
653653def  not_found (environ , start_response ):
654654    """Called if no URL matches.""" 
655655    resp  =  NotFound ('Not Found' )
@@ -659,7 +659,7 @@ def not_found(environ, start_response):
659659# ---------------------------------------------------------------------------- 
660660
661661
662- #noinspection PyUnusedLocal 
662+ #  noinspection PyUnusedLocal 
663663def  main (environ , start_response , sp ):
664664    user  =  CACHE .get_user (environ )
665665
@@ -687,10 +687,11 @@ def disco(environ, start_response, _sp):
687687    resp .headers .append (kaka )
688688    return  resp (environ , start_response )
689689
690+ 
690691# ---------------------------------------------------------------------------- 
691692
692693
693- #noinspection PyUnusedLocal 
694+ #  noinspection PyUnusedLocal 
694695def  logout (environ , start_response , sp ):
695696    user  =  CACHE .get_user (environ )
696697
@@ -737,10 +738,11 @@ def finish_logout(environ, start_response):
737738    cookie  =  CACHE .delete_cookie (environ )
738739
739740    resp  =  Response ('You are now logged out of this service' , headers = [
740-       cookie ,
741+          cookie ,
741742    ])
742743    return  resp (environ , start_response )
743744
745+ 
744746# ---------------------------------------------------------------------------- 
745747
746748# map urls to functions 
@@ -768,16 +770,17 @@ def add_urls():
768770    urls .append (("%s/redirect$"  %  base , (SLO , "redirect" , SP )))
769771    urls .append (("%s/redirect/(.*)$"  %  base , (SLO , "redirect" , SP )))
770772
773+ 
771774# ---------------------------------------------------------------------------- 
772775
773776def  metadata (environ , start_response ):
774777    try :
775778        path  =  _args .path 
776779        if  path  is  None  or  len (path ) ==  0 :
777-             path  =  os .path .dirname (os .path .abspath (  __file__   ))
780+             path  =  os .path .dirname (os .path .abspath (__file__ ))
778781        if  path [- 1 ] !=  "/" :
779782            path  +=  "/" 
780-         metadata  =  create_metadata_string (path + "sp_conf.py" , None ,
783+         metadata  =  create_metadata_string (path   +   "sp_conf.py" , None ,
781784                                          _args .valid , _args .cert , _args .keyfile ,
782785                                          _args .id , _args .name , _args .sign )
783786        start_response ('200 OK' , [('Content-Type' , "text/xml" )])
@@ -786,6 +789,7 @@ def metadata(environ, start_response):
786789        logger .error ("An error occured while creating metadata: %s" , ex .message )
787790        return  not_found (environ , start_response )
788791
792+ 
789793def  application (environ , start_response ):
790794    """ 
791795    The main WSGI application. Dispatch the current request to 
@@ -824,23 +828,12 @@ def application(environ, start_response):
824828        resp  =  BadRequest ("%s"  %  err )
825829        return  resp (environ , start_response )
826830    except  Exception  as  err :
827-         #_err = exception_trace("RUN", err) 
828-         #logging.error(exception_trace("RUN", _err)) 
831+         #  _err = exception_trace("RUN", err) 
832+         #  logging.error(exception_trace("RUN", _err)) 
829833        print (err , file = sys .stderr )
830834        resp  =  ServiceError ("%s"  %  err )
831835        return  resp (environ , start_response )
832836
833- # ---------------------------------------------------------------------------- 
834- 
835- HOST  =  service_conf .HOST 
836- PORT  =  service_conf .PORT 
837- # ------- HTTPS ------- 
838- # These should point to relevant files 
839- SERVER_CERT  =  service_conf .SERVER_CERT 
840- SERVER_KEY  =  service_conf .SERVER_KEY 
841- # This is of course the certificate chain for the CA that signed 
842- # your cert and all the way up to the top 
843- CERT_CHAIN  =  service_conf .CERT_CHAIN 
844837
845838if  __name__  ==  '__main__' :
846839    from  cherrypy  import  wsgiserver 
@@ -866,7 +859,8 @@ def application(environ, start_response):
866859    _parser .add_argument ('-n' , dest = 'name' )
867860    _parser .add_argument ('-S' , dest = 'sign' , action = 'store_true' ,
868861                         help = "sign the metadata" )
869- 
862+     _parser .add_argument ('-C' , dest = 'service_conf_module' ,
863+                          help = "service config module" )
870864
871865    ARGS  =  {}
872866    _args  =  _parser .parse_args ()
@@ -882,6 +876,21 @@ def application(environ, start_response):
882876    else :
883877        SEED  =  "SnabbtInspel" 
884878
879+     if  _args .service_conf_module :
880+         service_conf  =  importlib .import_module (_args .service_conf_module )
881+     else :
882+         import  service_conf 
883+ 
884+     HOST  =  service_conf .HOST 
885+     PORT  =  service_conf .PORT 
886+     # ------- HTTPS ------- 
887+     # These should point to relevant files 
888+     SERVER_CERT  =  service_conf .SERVER_CERT 
889+     SERVER_KEY  =  service_conf .SERVER_KEY 
890+     # This is of course the certificate chain for the CA that signed 
891+     # your cert and all the way up to the top 
892+     CERT_CHAIN  =  service_conf .CERT_CHAIN 
893+ 
885894    SP  =  Saml2Client (config_file = "%s"  %  CNFBASE )
886895
887896    POLICY  =  service_conf .POLICY 
@@ -904,6 +913,7 @@ def application(environ, start_response):
904913    _https  =  "" 
905914    if  service_conf .HTTPS :
906915        from  cherrypy .wsgiserver  import  ssl_pyopenssl 
916+ 
907917        SRV .ssl_adapter  =  ssl_pyopenssl .pyOpenSSLAdapter (SERVER_CERT ,
908918                                                         SERVER_KEY , CERT_CHAIN )
909919        _https  =  " using SSL/TLS" 
0 commit comments