<s> import logging <EOL> import os <EOL> import uuid <EOL> from flask import ( <EOL> Flask , <EOL> redirect , <EOL> render_template , <EOL> request , <EOL> session , <EOL> url_for , <EOL> ) <EOL> from flask . ext . login import ( <EOL> LoginManager , <EOL> UserMixin , <EOL> current_user , <EOL> login_required , <EOL> login_user , <EOL> logout_user , <EOL> ) <EOL> from flask_bootstrap import Bootstrap <EOL> from saml2 import ( <EOL> BINDING_HTTP_POST , <EOL> BINDING_HTTP_REDIRECT , <EOL> entity , <EOL> ) <EOL> from saml2 . client import Saml2Client <EOL> from saml2 . config import Config as Saml2Config <EOL> import requests <EOL> metadata_url_for = { <EOL> } <EOL> app = Flask ( __name__ ) <EOL> Bootstrap ( app ) <EOL> app . secret_key = str ( uuid . uuid4 ( ) ) <EOL> login_manager = LoginManager ( ) <EOL> login_manager . setup_app ( app ) <EOL> logging . basicConfig ( level = logging . DEBUG ) <EOL> user_store = { } <EOL> def saml_client_for ( idp_name = None ) : <EOL> '''<STR_LIT>''' <EOL> if idp_name not in metadata_url_for : <EOL> raise Exception ( "<STR_LIT>" . format ( idp_name ) ) <EOL> acs_url = url_for ( <EOL> "<STR_LIT>" , <EOL> idp_name = idp_name , <EOL> _external = True ) <EOL> https_acs_url = url_for ( <EOL> "<STR_LIT>" , <EOL> idp_name = idp_name , <EOL> _external = True , <EOL> _scheme = '<STR_LIT>' ) <EOL> rv = requests . get ( metadata_url_for [ idp_name ] ) <EOL> settings = { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : [ rv . text ] , <EOL> } , <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : { <EOL> '<STR_LIT>' : [ <EOL> ( acs_url , BINDING_HTTP_REDIRECT ) , <EOL> ( acs_url , BINDING_HTTP_POST ) , <EOL> ( https_acs_url , BINDING_HTTP_REDIRECT ) , <EOL> ( https_acs_url , BINDING_HTTP_POST ) <EOL> ] , <EOL> } , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : False , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : True , <EOL> '<STR_LIT>' : False , <EOL> } , <EOL> } , <EOL> } <EOL> spConfig = Saml2Config ( ) <EOL> spConfig . load ( settings ) <EOL> spConfig . allow_unknown_attributes = True <EOL> saml_client = Saml2Client ( config = spConfig ) <EOL> return saml_client <EOL> class User ( UserMixin ) : <EOL> def __init__ ( self , user_id ) : <EOL> user = { } <EOL> self . id = None <EOL> self . first_name = None <EOL> self . last_name = None <EOL> try : <EOL> user = user_store [ user_id ] <EOL> self . id = unicode ( user_id ) <EOL> self . first_name = user [ '<STR_LIT>' ] <EOL> self . last_name = user [ '<STR_LIT>' ] <EOL> except : <EOL> pass <EOL> @ login_manager . user_loader <EOL> def load_user ( user_id ) : <EOL> return User ( user_id ) <EOL> @ app . route ( "<STR_LIT:/>" ) <EOL> def main_page ( ) : <EOL> return render_template ( '<STR_LIT>' , idp_dict = metadata_url_for ) <EOL> @ app . route ( "<STR_LIT>" , methods = [ '<STR_LIT:POST>' ] ) <EOL> def idp_initiated ( idp_name ) : <EOL> saml_client = saml_client_for ( idp_name ) <EOL> authn_response = saml_client . parse_authn_request_response ( <EOL> request . form [ '<STR_LIT>' ] , <EOL> entity . BINDING_HTTP_POST ) <EOL> authn_response . get_identity ( ) <EOL> user_info = authn_response . get_subject ( ) <EOL> username = user_info . text <EOL> if username not in user_store : <EOL> user_store [ username ] = { <EOL> '<STR_LIT>' : authn_response . ava [ '<STR_LIT>' ] [ <NUM_LIT:0> ] , <EOL> '<STR_LIT>' : authn_response . ava [ '<STR_LIT>' ] [ <NUM_LIT:0> ] , <EOL> } <EOL> user = User ( username ) <EOL> session [ '<STR_LIT>' ] = authn_response . ava <EOL> login_user ( user ) <EOL> url = url_for ( '<STR_LIT:user>' ) <EOL> if '<STR_LIT>' in request . form : <EOL> url = request . form [ '<STR_LIT>' ] <EOL> return redirect ( url ) <EOL> @ app . route ( "<STR_LIT>" ) <EOL> def sp_initiated ( idp_name ) : <EOL> saml_client = saml_client_for ( idp_name ) <EOL> reqid , info = saml_client . prepare_for_authenticate ( ) <EOL> redirect_url = None <EOL> for key , value in info [ '<STR_LIT>' ] : <EOL> if key is '<STR_LIT>' : <EOL> redirect_url = value <EOL> response = redirect ( redirect_url , code = <NUM_LIT> ) <EOL> response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> response . headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> return response <EOL> @ app . route ( "<STR_LIT>" ) <EOL> @ login_required <EOL> def user ( ) : <EOL> return render_template ( '<STR_LIT>' , session = session ) <EOL> @ app . errorhandler ( <NUM_LIT> ) <EOL> def error_unauthorized ( error ) : <EOL> return render_template ( '<STR_LIT>' ) <EOL> @ app . route ( "<STR_LIT>" ) <EOL> @ login_required <EOL> def logout ( ) : <EOL> logout_user ( ) <EOL> return redirect ( url_for ( "<STR_LIT>" ) ) <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> port = int ( os . environ . get ( '<STR_LIT>' , <NUM_LIT> ) ) <EOL> if port == <NUM_LIT> : <EOL> app . debug = True <EOL> app . run ( host = '<STR_LIT>' , port = port ) </s>
