From 555cb99c86f87bc259141d4767f4e3abc2032235 Mon Sep 17 00:00:00 2001 From: Maciej Pienczyn Date: Wed, 11 Mar 2026 07:32:43 +0100 Subject: [PATCH] feat: capture and display Google account email for OAuth connections After token exchange, fetches Google userinfo to save the email and name of the Google account used for authorization. Displays this info on the GBP audit page so users know which account to reconnect with. Co-Authored-By: Claude Opus 4.6 --- blueprints/audit/routes.py | 2 ++ oauth_service.py | 24 +++++++++++++++++++++++- templates/gbp_audit.html | 4 +++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/blueprints/audit/routes.py b/blueprints/audit/routes.py index 7d31a16..67f1427 100644 --- a/blueprints/audit/routes.py +++ b/blueprints/audit/routes.py @@ -521,6 +521,8 @@ def gbp_audit_dashboard(slug): 'created_at': gbp_oauth_token.created_at, 'expires_at': gbp_oauth_token.expires_at, 'has_refresh_token': bool(gbp_oauth_token.refresh_token), + 'google_email': gbp_oauth_token.account_id, + 'google_name': gbp_oauth_token.account_name, } logger.info(f"GBP audit dashboard viewed by {current_user.email} for company: {company.name}") diff --git a/oauth_service.py b/oauth_service.py index 61bd59c..ebbb91a 100644 --- a/oauth_service.py +++ b/oauth_service.py @@ -141,7 +141,24 @@ class OAuthService: if response.status_code != 200: logger.error(f"OAuth token exchange failed for {provider}: {response.status_code} - {response.text}") return None - return response.json() + token_data = response.json() + + # For Google: fetch user email to identify which account was used + if provider == 'google' and token_data.get('access_token'): + try: + userinfo_resp = requests.get( + 'https://www.googleapis.com/oauth2/v2/userinfo', + headers={'Authorization': f"Bearer {token_data['access_token']}"}, + timeout=10 + ) + if userinfo_resp.status_code == 200: + userinfo = userinfo_resp.json() + token_data['google_email'] = userinfo.get('email') + token_data['google_name'] = userinfo.get('name') + except Exception as e: + logger.warning(f"Could not fetch Google userinfo: {e}") + + return token_data except Exception as e: logger.error(f"OAuth token exchange error for {provider}: {e}") return None @@ -264,6 +281,11 @@ class OAuthService: token.is_active = True token.updated_at = datetime.now() + # Save Google account identity if available + if token_data.get('google_email'): + token.account_id = token_data['google_email'] + token.account_name = token_data.get('google_name', token_data['google_email']) + db.commit() logger.info(f"OAuth token saved: {provider}/{service} for company {company_id}") return True diff --git a/templates/gbp_audit.html b/templates/gbp_audit.html index 0faedd9..42ddfef 100644 --- a/templates/gbp_audit.html +++ b/templates/gbp_audit.html @@ -970,6 +970,7 @@ Konsola Google Business Profile połączona

Dostępne są pełne dane: wyświetlenia, wyszukiwania, kliknięcia i interakcje klientów. + {% if gbp_connection.google_email %}Konto: {{ gbp_connection.google_email }}.{% endif %} {% if gbp_connection.created_at %}Połączone od {{ gbp_connection.created_at.strftime('%d.%m.%Y') }}.{% endif %}

@@ -982,7 +983,8 @@ Połączenie z konsolą GBP wygasło

Autoryzacja Google wygasła{% if gbp_connection.expires_at %} {{ gbp_connection.expires_at.strftime('%d.%m.%Y') }}{% endif %}. - Dane audytu pochodzą z publicznego API. Połącz ponownie, aby uzyskać pełne statystyki. + {% if gbp_connection.google_email %}Ostatnio użyte konto: {{ gbp_connection.google_email }}.{% endif %} + Połącz ponownie tym samym kontem, aby przywrócić pełne statystyki.

Połącz ponownie