| from flask import Blueprint, request, jsonify, current_app |
| from flask_jwt_extended import jwt_required, get_jwt_identity |
| from backend.services.linkedin_service import LinkedInService |
| import secrets |
|
|
| accounts_bp = Blueprint('accounts', __name__) |
|
|
| @accounts_bp.route('/', methods=['OPTIONS']) |
| @accounts_bp.route('', methods=['OPTIONS']) |
| def handle_options(): |
| """Handle OPTIONS requests for preflight CORS checks.""" |
| return '', 200 |
|
|
| @accounts_bp.route('/', methods=['GET']) |
| @accounts_bp.route('', methods=['GET']) |
| @jwt_required() |
| def get_accounts(): |
| """ |
| Get all social media accounts for the current user. |
| |
| Returns: |
| JSON: List of social media accounts |
| """ |
| try: |
| user_id = get_jwt_identity() |
| |
| |
| if not hasattr(current_app, 'supabase') or current_app.supabase is None: |
| |
| response_data = jsonify({ |
| 'success': False, |
| 'message': 'Database connection not initialized' |
| }) |
| response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
| response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
| return response_data, 500 |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Social_network") |
| .select("*") |
| .eq("id_utilisateur", user_id) |
| .execute() |
| ) |
| |
| accounts = response.data if response.data else [] |
| |
| |
| response_data = jsonify({ |
| 'success': True, |
| 'accounts': accounts |
| }) |
| response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
| response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
| return response_data, 200 |
| |
| except Exception as e: |
| current_app.logger.error(f"Get accounts error: {str(e)}") |
| |
| response_data = jsonify({ |
| 'success': False, |
| 'message': 'An error occurred while fetching accounts' |
| }) |
| response_data.headers.add('Access-Control-Allow-Origin', 'http://localhost:3000') |
| response_data.headers.add('Access-Control-Allow-Credentials', 'true') |
| return response_data, 500 |
|
|
| @accounts_bp.route('/', methods=['POST']) |
| @accounts_bp.route('', methods=['POST']) |
| @jwt_required() |
| def add_account(): |
| """ |
| Add a new social media account for the current user. |
| |
| Request Body: |
| account_name (str): Account name |
| social_network (str): Social network name |
| |
| Returns: |
| JSON: Add account result |
| """ |
| try: |
| user_id = get_jwt_identity() |
| data = request.get_json() |
| |
| |
| if not data or not all(k in data for k in ('account_name', 'social_network')): |
| return jsonify({ |
| 'success': False, |
| 'message': 'Account name and social network are required' |
| }), 400 |
| |
| account_name = data['account_name'] |
| social_network = data['social_network'] |
| |
| |
| if social_network.lower() == 'linkedin': |
| linkedin_service = LinkedInService() |
| |
| state = secrets.token_urlsafe(32) |
| |
| |
| |
| authorization_url = linkedin_service.get_authorization_url(state) |
| |
| return jsonify({ |
| 'success': True, |
| 'message': 'Please authenticate with LinkedIn', |
| 'authorization_url': authorization_url, |
| 'state': state |
| }), 200 |
| else: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Unsupported social network' |
| }), 400 |
| |
| except Exception as e: |
| current_app.logger.error(f"Add account error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred while adding account: {str(e)}' |
| }), 500 |
|
|
| @accounts_bp.route('/callback', methods=['POST']) |
| @jwt_required() |
| def handle_oauth_callback(): |
| """ |
| Handle OAuth callback from social network. |
| |
| Request Body: |
| code (str): Authorization code |
| state (str): State parameter |
| social_network (str): Social network name |
| |
| Returns: |
| JSON: OAuth callback result |
| """ |
| try: |
| user_id = get_jwt_identity() |
| data = request.get_json() |
| |
| |
| if not data or not all(k in data for k in ('code', 'state', 'social_network')): |
| return jsonify({ |
| 'success': False, |
| 'message': 'Code, state, and social network are required' |
| }), 400 |
| |
| code = data['code'] |
| state = data['state'] |
| social_network = data['social_network'] |
| |
| |
| |
| |
| if social_network.lower() == 'linkedin': |
| linkedin_service = LinkedInService() |
| |
| |
| token_response = linkedin_service.get_access_token(code) |
| access_token = token_response['access_token'] |
| |
| |
| user_info = linkedin_service.get_user_info(access_token) |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Social_network") |
| .insert({ |
| "social_network": social_network, |
| "account_name": user_info.get('name', 'LinkedIn Account'), |
| "id_utilisateur": user_id, |
| "token": access_token, |
| "sub": user_info.get('sub'), |
| "given_name": user_info.get('given_name'), |
| "family_name": user_info.get('family_name'), |
| "picture": user_info.get('picture') |
| }) |
| .execute() |
| ) |
| |
| if response.data: |
| return jsonify({ |
| 'success': True, |
| 'message': 'Account linked successfully', |
| 'account': response.data[0] |
| }), 200 |
| else: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Failed to link account' |
| }), 500 |
| else: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Unsupported social network' |
| }), 400 |
| |
| except Exception as e: |
| current_app.logger.error(f"OAuth callback error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': f'An error occurred during OAuth callback: {str(e)}' |
| }), 500 |
|
|
| @accounts_bp.route('/<account_id>', methods=['OPTIONS']) |
| def handle_account_options(account_id): |
| """Handle OPTIONS requests for preflight CORS checks for specific account.""" |
| return '', 200 |
|
|
| @accounts_bp.route('/<account_id>', methods=['DELETE']) |
| @jwt_required() |
| def delete_account(account_id): |
| """ |
| Delete a social media account. |
| |
| Path Parameters: |
| account_id (str): Account ID |
| |
| Returns: |
| JSON: Delete account result |
| """ |
| try: |
| user_id = get_jwt_identity() |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Social_network") |
| .delete() |
| .eq("id", account_id) |
| .eq("id_utilisateur", user_id) |
| .execute() |
| ) |
| |
| if response.data: |
| return jsonify({ |
| 'success': True, |
| 'message': 'Account deleted successfully' |
| }), 200 |
| else: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Account not found or unauthorized' |
| }), 404 |
| |
| except Exception as e: |
| current_app.logger.error(f"Delete account error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': 'An error occurred while deleting account' |
| }), 500 |
|
|
| @accounts_bp.route('/<account_id>/primary', methods=['OPTIONS']) |
| def handle_primary_options(account_id): |
| """Handle OPTIONS requests for preflight CORS checks for primary account.""" |
| return '', 200 |
|
|
| @accounts_bp.route('/<account_id>/primary', methods=['PUT']) |
| @jwt_required() |
| def set_primary_account(account_id): |
| """ |
| Set an account as primary for the user. |
| |
| Path Parameters: |
| account_id (str): Account ID |
| |
| Returns: |
| JSON: Update result |
| """ |
| try: |
| user_id = get_jwt_identity() |
| |
| |
| response = ( |
| current_app.supabase |
| .table("Social_network") |
| .select("*") |
| .eq("id_utilisateur", user_id) |
| .execute() |
| ) |
| |
| accounts = response.data if response.data else [] |
| |
| |
| account_exists = any(account['id'] == account_id and account['id_utilisateur'] == user_id for account in accounts) |
| |
| if not account_exists: |
| return jsonify({ |
| 'success': False, |
| 'message': 'Account not found or unauthorized' |
| }), 404 |
| |
| |
| |
| |
| |
| return jsonify({ |
| 'success': True, |
| 'message': 'Account set as primary successfully' |
| }), 200 |
| |
| except Exception as e: |
| current_app.logger.error(f"Set primary account error: {str(e)}") |
| return jsonify({ |
| 'success': False, |
| 'message': 'An error occurred while setting primary account' |
| }), 500 |