@@ -96,21 +96,49 @@ def received_activity(self, data):
9696 else :
9797 cla .log .debug ("github_models.received_activity - Ignoring unsupported action: {}" .format (data ["action" ]))
9898
99- def user_from_session (self , request , redirect ):
100- fn = "github_models.user_from_session" # function name
99+ def user_from_session (self , request , redirect , redirect_url , state , code ):
100+ fn = "github_models.user_from_session"
101101 cla .log .debug (f"{ fn } - Loading session from request: { request } ..." )
102102 session = self ._get_request_session (request )
103+ cla .log .debug (f"{ fn } - redirect: { redirect } , redirect_url: { redirect_url } , state: { state } , code: { code } , session: { session } " )
104+
105+ # we can already have token in the session
103106 if "github_oauth2_token" in session :
104107 cla .log .debug (f"{ fn } - Using existing session GitHub OAuth2 token" )
105108 user = self .get_or_create_user (request )
106109 cla .log .debug (f"{ fn } - loaded user { user .to_dict ()} " )
107110 return user
111+
112+ # if not then we can either request a new OAuth2 GitHub authentication or user code & state from GitHub to create a session
113+ if code and state :
114+ session_state = None
115+ if "github_oauth2_state" in session :
116+ session_state = session ["github_oauth2_state" ]
117+ cla .log .warning (f"{ fn } - github_oauth2_state in current session: { session_state } " )
118+ else :
119+ cla .log .warning (f"{ fn } - github_oauth2_state not set in current session" )
120+ if session_state and state != session_state :
121+ cla .log .warning (f"{ fn } - invalid GitHub OAuth2 state { session_state } expecting { state } " )
122+ raise falcon .HTTPBadRequest (f"Invalid OAuth2 state: '{ session_state } ' != '{ state } '" )
123+ token_url = cla .conf ["GITHUB_OAUTH_TOKEN_URL" ]
124+ client_id = os .environ ["GH_OAUTH_CLIENT_ID" ]
125+ client_secret = os .environ ["GH_OAUTH_SECRET" ]
126+ try :
127+ token = self ._fetch_token (client_id , state , token_url , client_secret , code )
128+ except Exception as err :
129+ cla .log .warning (f"{ fn } - GitHub OAuth2 error: { err } . Likely bad or expired code." )
130+ raise falcon .HTTPBadRequest ("OAuth2 code is invalid or expired" )
131+ cla .log .debug (f"{ fn } - oauth2 token received for state { state } : { token } - storing token in session" )
132+ session ["github_oauth2_token" ] = token
133+ user = self .get_or_create_user (request )
134+ cla .log .debug (f"{ fn } - loaded user { user .to_dict ()} " )
135+ return user
108136 else :
109137 cla .log .debug (f"{ fn } - No existing GitHub OAuth2 token - building authorization url and state" )
110- authorization_url , state = self .get_authorization_url_and_state ( None , None , None , [ "user:email" ] )
138+ authorization_url , new_state = self .get_github_oauth2_redirect_url_and_state ( redirect_url )
111139 cla .log .debug (f"{ fn } - Obtained GitHub OAuth2 state from authorization - storing state in the session..." )
112- session ["github_oauth2_state" ] = state
113- cla .log .debug (f"{ fn } - GitHub OAuth2 request with state { state } - sending user to { authorization_url } " )
140+ session ["github_oauth2_state" ] = new_state
141+ cla .log .debug (f"{ fn } - GitHub OAuth2 request with state { new_state } - sending user to { authorization_url } " )
114142 if redirect :
115143 raise falcon .HTTPFound (authorization_url )
116144 else :
@@ -176,6 +204,25 @@ def _get_request_session(self, request) -> dict: # pylint: disable=no-self-use
176204
177205 return session
178206
207+ def get_github_oauth2_redirect_url_and_state (self , redirect_uri ):
208+ fn = "github_models.get_github_oauth2_redirect_url_and_state"
209+ github_oauth_url = cla .conf ["GITHUB_OAUTH_AUTHORIZE_URL" ]
210+ github_oauth_client_id = os .environ ["GH_OAUTH_CLIENT_ID" ]
211+ if not redirect_uri :
212+ redirect_uri = os .environ .get ("CLA_API_BASE" , "" ).strip () + "/v2/user-from-session"
213+
214+ scope = ["user:email" ]
215+ cla .log .debug (
216+ f"{ fn } - Directing user to the github authorization url: { github_oauth_url } via "
217+ f"our github installation flow: { redirect_uri } "
218+ f"using the github oauth client id: { github_oauth_client_id [0 :5 ]} "
219+ f"with scope: { scope } "
220+ )
221+
222+ return self ._get_authorization_url_and_state (
223+ client_id = github_oauth_client_id , redirect_uri = redirect_uri , scope = scope , authorize_url = github_oauth_url
224+ )
225+
179226 def get_authorization_url_and_state (self , installation_id , github_repository_id , pull_request_number , scope ):
180227 """
181228 Helper method to get the GitHub OAuth2 authorization URL and state.
@@ -1848,7 +1895,7 @@ def _fetch_token(self, client_id, state, token_url, client_secret, code): # pyl
18481895 def _get_request_session (self , request ) -> dict :
18491896 if self .oauth2_token :
18501897 return {
1851- "github_oauth2_token" : "random-token" ,
1898+ "github_oauth2_token" : "random-token" , # LG: comment this out to see how Mock class woudl attempt to fetch GitHub token using state & code
18521899 "github_oauth2_state" : "random-state" ,
18531900 "github_origin_url" : "http://github/origin/url" ,
18541901 "github_installation_id" : 1 ,
0 commit comments