<s> """<STR_LIT>""" <EOL> import uuid <EOL> from pyramid . httpexceptions import HTTPFound <EOL> from pyramid . security import NO_PERMISSION_REQUIRED <EOL> import requests <EOL> from . . api import ( <EOL> AuthenticationComplete , <EOL> AuthenticationDenied , <EOL> register_provider , <EOL> ) <EOL> from . . compat import parse_qsl <EOL> from . . exceptions import CSRFError <EOL> from . . exceptions import ThirdPartyFailure <EOL> from . . settings import ProviderSettings <EOL> from . . utils import flat_url <EOL> class GithubAuthenticationComplete ( AuthenticationComplete ) : <EOL> """<STR_LIT>""" <EOL> def includeme ( config ) : <EOL> config . add_directive ( '<STR_LIT>' , add_github_login ) <EOL> config . add_directive ( '<STR_LIT>' , <EOL> add_github_login_from_settings ) <EOL> def add_github_login_from_settings ( config , prefix = '<STR_LIT>' ) : <EOL> settings = config . registry . settings <EOL> p = ProviderSettings ( settings , prefix ) <EOL> p . update ( '<STR_LIT>' , required = True ) <EOL> p . update ( '<STR_LIT>' , required = True ) <EOL> p . update ( '<STR_LIT>' ) <EOL> p . update ( '<STR_LIT>' ) <EOL> p . update ( '<STR_LIT>' ) <EOL> p . update ( '<STR_LIT>' ) <EOL> p . update ( '<STR_LIT>' ) <EOL> config . add_github_login ( ** p . kwargs ) <EOL> def add_github_login ( config , <EOL> consumer_key , <EOL> consumer_secret , <EOL> scope = None , <EOL> login_path = '<STR_LIT>' , <EOL> callback_path = '<STR_LIT>' , <EOL> secure = True , <EOL> domain = '<STR_LIT>' , <EOL> name = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> provider = GithubProvider ( name , <EOL> consumer_key , <EOL> consumer_secret , <EOL> scope , <EOL> secure , <EOL> domain ) <EOL> config . add_route ( provider . login_route , login_path ) <EOL> config . add_view ( provider , attr = '<STR_LIT>' , route_name = provider . login_route , <EOL> permission = NO_PERMISSION_REQUIRED ) <EOL> config . add_route ( provider . callback_route , callback_path , <EOL> use_global_views = True , <EOL> factory = provider . callback ) <EOL> register_provider ( config , name , provider ) <EOL> class GithubProvider ( object ) : <EOL> def __init__ ( self , <EOL> name , <EOL> consumer_key , <EOL> consumer_secret , <EOL> scope , <EOL> secure , <EOL> domain ) : <EOL> self . name = name <EOL> self . type = '<STR_LIT>' <EOL> self . consumer_key = consumer_key <EOL> self . consumer_secret = consumer_secret <EOL> self . scope = scope <EOL> self . protocol = '<STR_LIT:http>' if secure is False else '<STR_LIT>' <EOL> self . domain = domain <EOL> self . login_route = '<STR_LIT>' % name <EOL> self . callback_route = '<STR_LIT>' % name <EOL> def login ( self , request ) : <EOL> """<STR_LIT>""" <EOL> scope = request . POST . get ( '<STR_LIT>' , self . scope ) <EOL> request . session [ '<STR_LIT>' ] = state = uuid . uuid4 ( ) . hex <EOL> gh_url = flat_url ( <EOL> '<STR_LIT>' % ( self . protocol , self . domain ) , <EOL> scope = scope , <EOL> client_id = self . consumer_key , <EOL> redirect_uri = request . route_url ( self . callback_route ) , <EOL> state = state ) <EOL> return HTTPFound ( location = gh_url ) <EOL> def callback ( self , request ) : <EOL> """<STR_LIT>""" <EOL> sess_state = request . session . pop ( '<STR_LIT>' , None ) <EOL> req_state = request . GET . get ( '<STR_LIT:state>' ) <EOL> if not sess_state or sess_state != req_state : <EOL> raise CSRFError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' . format ( <EOL> req_state = req_state , <EOL> sess_state = sess_state <EOL> ) <EOL> ) <EOL> code = request . GET . get ( '<STR_LIT:code>' ) <EOL> if not code : <EOL> reason = request . GET . get ( '<STR_LIT:error>' , '<STR_LIT>' ) <EOL> return AuthenticationDenied ( reason = reason , <EOL> provider_name = self . name , <EOL> provider_type = self . type ) <EOL> access_url = flat_url ( <EOL> '<STR_LIT>' % ( self . protocol , self . domain ) , <EOL> client_id = self . consumer_key , <EOL> client_secret = self . consumer_secret , <EOL> redirect_uri = request . route_url ( self . callback_route ) , <EOL> code = code ) <EOL> r = requests . get ( access_url ) <EOL> if r . status_code != <NUM_LIT:200> : <EOL> raise ThirdPartyFailure ( "<STR_LIT>" % ( <EOL> r . status_code , r . content ) ) <EOL> access_token = dict ( parse_qsl ( r . text ) ) [ '<STR_LIT>' ] <EOL> graph_url = flat_url ( '<STR_LIT>' % ( self . protocol , self . domain ) , <EOL> access_token = access_token ) <EOL> graph_headers = dict ( Accept = '<STR_LIT>' ) <EOL> r = requests . get ( graph_url , headers = graph_headers ) <EOL> if r . status_code != <NUM_LIT:200> : <EOL> raise ThirdPartyFailure ( "<STR_LIT>" % ( <EOL> r . status_code , r . content ) ) <EOL> data = r . json ( ) <EOL> profile = { } <EOL> profile [ '<STR_LIT>' ] = [ { <EOL> '<STR_LIT>' : self . domain , <EOL> '<STR_LIT:username>' : data [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : data [ '<STR_LIT:id>' ] <EOL> } ] <EOL> profile [ '<STR_LIT>' ] = data [ '<STR_LIT>' ] <EOL> profile [ '<STR_LIT>' ] = data . get ( '<STR_LIT:name>' , profile [ '<STR_LIT>' ] ) <EOL> if '<STR_LIT:email>' in data : <EOL> profile [ '<STR_LIT>' ] = [ { '<STR_LIT:value>' : data [ '<STR_LIT:email>' ] } ] <EOL> cred = { '<STR_LIT>' : access_token } <EOL> return GithubAuthenticationComplete ( profile = profile , <EOL> credentials = cred , <EOL> provider_name = self . name , <EOL> provider_type = self . type ) </s>
