feat: Add internal API endpoints for Customer Panel integration

- Add internal_api_required decorator for internal API authentication
- Add /internal/available endpoint to fetch available CF accounts
- Add /internal/<id> endpoint to get CF account with API token
- Filter accounts by is_active and use_for_verification flags
- Require X-Internal-API-Key header for internal endpoints
This commit is contained in:
oguz ozturk 2026-01-12 16:58:06 +03:00
parent e149c56f76
commit d68c4d38ff
1 changed files with 84 additions and 0 deletions

View File

@ -4,9 +4,21 @@ Cloudflare Accounts Management Routes
from flask import Blueprint, request, jsonify from flask import Blueprint, request, jsonify
from app.models import db, CloudflareAccount, AuditLog from app.models import db, CloudflareAccount, AuditLog
from app.routes.auth import token_required from app.routes.auth import token_required
from app.config import Config
from functools import wraps
cf_accounts_bp = Blueprint('cf_accounts', __name__) cf_accounts_bp = Blueprint('cf_accounts', __name__)
def internal_api_required(f):
"""Decorator for internal API endpoints (requires internal API key)"""
@wraps(f)
def decorated_function(*args, **kwargs):
api_key = request.headers.get('X-Internal-API-Key')
if not api_key or api_key != Config.CUSTOMER_API_INTERNAL_KEY:
return jsonify({'error': 'Unauthorized - Invalid internal API key'}), 401
return f(*args, **kwargs)
return decorated_function
@cf_accounts_bp.route('', methods=['GET']) @cf_accounts_bp.route('', methods=['GET'])
@token_required @token_required
def get_cf_accounts(current_admin): def get_cf_accounts(current_admin):
@ -170,3 +182,75 @@ def delete_cf_account(current_admin, account_id):
db.session.rollback() db.session.rollback()
return jsonify({'error': str(e)}), 500 return jsonify({'error': str(e)}), 500
# Internal API Endpoints (for Customer Panel)
@cf_accounts_bp.route('/internal/available', methods=['GET'])
@internal_api_required
def get_available_cf_accounts_internal():
"""
Internal API endpoint for Customer Panel to fetch available CF accounts
Requires X-Internal-API-Key header
"""
try:
# Get active CF accounts that are enabled for verification
accounts = CloudflareAccount.query.filter_by(
is_active=True,
use_for_verification=True
).order_by(CloudflareAccount.created_at.desc()).all()
result = []
for account in accounts:
account_dict = account.to_dict(include_token=False)
# Calculate available capacity
account_dict['available_capacity'] = account.max_domains - account.current_domains
account_dict['is_full'] = account.current_domains >= account.max_domains
result.append(account_dict)
return jsonify({
'status': 'success',
'accounts': result,
'total': len(result)
}), 200
except Exception as e:
return jsonify({
'status': 'error',
'error': str(e)
}), 500
@cf_accounts_bp.route('/internal/<int:account_id>', methods=['GET'])
@internal_api_required
def get_cf_account_internal(account_id):
"""
Internal API endpoint to get specific CF account with API token
Requires X-Internal-API-Key header
"""
try:
account = CloudflareAccount.query.get(account_id)
if not account:
return jsonify({
'status': 'error',
'error': 'Account not found'
}), 404
if not account.is_active or not account.use_for_verification:
return jsonify({
'status': 'error',
'error': 'Account not available for verification'
}), 403
# Return account with API token (for internal use)
account_dict = account.to_dict(include_token=True)
return jsonify({
'status': 'success',
'account': account_dict
}), 200
except Exception as e:
return jsonify({
'status': 'error',
'error': str(e)
}), 500