Skip to content

Commit 8b14aaa

Browse files
committed
feat: implement Instagram-specific OAuth2 refresh token logic
1 parent 9efd439 commit 8b14aaa

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

backend/aci/server/oauth2_manager.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ async def fetch_token(
202202
f"Missing access_token in Instagram OAuth response, app={self.app_name}"
203203
)
204204
raise OAuth2Error("Missing access_token in Instagram OAuth response")
205+
205206
# return the token response with long-lived access token
206207
return token
207208
except Exception as e:
@@ -210,15 +211,28 @@ async def fetch_token(
210211

211212
async def refresh_token(
212213
self,
214+
access_token: str,
213215
refresh_token: str,
214216
) -> dict[str, Any]:
215217
try:
216-
token = cast(
217-
dict[str, Any],
218-
await self.oauth2_client.refresh_token(
219-
self.refresh_token_url, refresh_token=refresh_token
220-
),
221-
)
218+
if self.app_name == "INSTAGRAM":
219+
response = await self.oauth2_client.get(
220+
self.refresh_token_url,
221+
params={
222+
"grant_type": "ig_refresh_token",
223+
"access_token": access_token,
224+
},
225+
timeout=30.0,
226+
)
227+
response.raise_for_status()
228+
token = cast(dict[str, Any], response.json())
229+
else:
230+
token = cast(
231+
dict[str, Any],
232+
await self.oauth2_client.refresh_token(
233+
self.refresh_token_url, refresh_token=refresh_token
234+
),
235+
)
222236
return token
223237
except Exception as e:
224238
logger.error(f"Failed to refresh access token, app_name={self.app_name}, error={e}")
@@ -253,7 +267,11 @@ async def parse_fetch_token_response(self, token: dict) -> OAuth2SchemeCredentia
253267
if "expires_at" in data:
254268
expires_at = int(data["expires_at"])
255269
elif "expires_in" in data:
256-
expires_at = int(time.time()) + int(data["expires_in"])
270+
if self.app_name == "INSTAGRAM":
271+
# Reduce expiration time by 1 day (86400 seconds) for safety margin
272+
expires_at = int(time.time()) + max(0, int(data["expires_in"]) - 86400)
273+
else:
274+
expires_at = int(time.time()) + int(data["expires_in"])
257275

258276
# TODO: if scope is present, check if it matches the scope in the App Configuration
259277

backend/aci/server/security_credentials_manager.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ async def _get_oauth2_credentials(
9797
linked_account.security_credentials
9898
)
9999
if _access_token_is_expired(oauth2_scheme_credentials):
100+
# Instagram's access token only could be refreshed with a valid access token, so we need to re-authorize
100101
if app.name == "INSTAGRAM":
101102
logger.error(
102103
f"Access token expired, please re-authorize, linked_account_id={linked_account.id}, "
@@ -120,7 +121,11 @@ async def _get_oauth2_credentials(
120121
if "expires_at" in token_response:
121122
expires_at = int(token_response["expires_at"])
122123
elif "expires_in" in token_response:
123-
expires_at = int(time.time()) + int(token_response["expires_in"])
124+
if app.name == "INSTAGRAM":
125+
# Reduce expiration time by 1 day (86400 seconds) for safety margin
126+
expires_at = int(time.time()) + max(0, int(token_response["expires_in"]) - 86400)
127+
else:
128+
expires_at = int(time.time()) + int(token_response["expires_in"])
124129

125130
if not token_response.get("access_token") or not expires_at:
126131
logger.error(
@@ -155,6 +160,8 @@ async def _refresh_oauth2_access_token(
155160
app_name: str, oauth2_scheme: OAuth2Scheme, oauth2_scheme_credentials: OAuth2SchemeCredentials
156161
) -> dict:
157162
refresh_token = oauth2_scheme_credentials.refresh_token
163+
access_token = oauth2_scheme_credentials.access_token
164+
158165
if not refresh_token:
159166
raise OAuth2Error("no refresh token found")
160167

@@ -172,7 +179,7 @@ async def _refresh_oauth2_access_token(
172179
custom_data=oauth2_scheme.custom_data,
173180
)
174181

175-
return await oauth2_manager.refresh_token(refresh_token)
182+
return await oauth2_manager.refresh_token(refresh_token, access_token)
176183

177184

178185
def _get_api_key_credentials(

0 commit comments

Comments
 (0)