""" Mobile-First Ticketing Application with Biometric Authentication Cross-platform mobile app for secure ticket purchasing and management """ import json import hashlib import datetime import base64 import math import random from typing import Dict, List, Optional, Any, Union, Tuple from dataclasses import dataclass, asdict from collections import defaultdict @dataclass class UserProfile: user_id: str email: str phone: str biometric_enabled: bool biometric_type: str # 'fingerprint', 'face_id', 'voice' created_at: str last_login: str @dataclass class Ticket: ticket_id: str event_id: str event_name: str event_date: str venue: str seat: str price: float qr_code: str purchase_date: str status: str @dataclass class BiometricData: user_id: str biometric_hash: str biometric_type: str created_at: str device_id: str class MobileTicketingApp: """Mobile-first ticketing application with biometric security""" def __init__(self): self.users = {} self.tickets = defaultdict(list) self.biometric_data = {} self.sessions = {} self.device_registrations = {} self.app_settings = { 'biometric_required': True, 'session_timeout': 3600, # 1 hour 'max_devices_per_user': 3, 'offline_ticket_duration': 86400 # 24 hours } def register_user(self, user_data: Dict[str, Any]) -> Dict[str, Any]: """Register new user account""" user_id = self._generate_user_id() # Validate user data if not self._validate_user_data(user_data): return {'success': False, 'error': 'Invalid user data'} # Create user profile user_profile = UserProfile( user_id=user_id, email=user_data['email'], phone=user_data['phone'], biometric_enabled=False, biometric_type='', created_at=datetime.datetime.now().isoformat(), last_login=datetime.datetime.now().isoformat() ) self.users[user_id] = user_profile return { 'success': True, 'user_id': user_id, 'message': 'User registered successfully' } def enable_biometric_auth(self, auth_data: Dict[str, Any]) -> Dict[str, Any]: """Enable biometric authentication for user""" user_id = auth_data['user_id'] biometric_type = auth_data['biometric_type'] device_id = auth_data['device_id'] biometric_template = auth_data['biometric_template'] if user_id not in self.users: return {'success': False, 'error': 'User not found'} # Create biometric hash (simulated) biometric_hash = self._create_biometric_hash(biometric_template, user_id, device_id) # Store biometric data biometric_record = BiometricData( user_id=user_id, biometric_hash=biometric_hash, biometric_type=biometric_type, created_at=datetime.datetime.now().isoformat(), device_id=device_id ) self.biometric_data[user_id] = biometric_record # Update user profile self.users[user_id].biometric_enabled = True self.users[user_id].biometric_type = biometric_type # Register device self._register_device(user_id, device_id) return { 'success': True, 'message': f'Biometric authentication enabled for {biometric_type}', 'device_registered': True } def authenticate_biometric(self, auth_request: Dict[str, Any]) -> Dict[str, Any]: """Authenticate user using biometric data""" user_id = auth_request['user_id'] device_id = auth_request['device_id'] biometric_input = auth_request['biometric_input'] # Check if user has biometric enabled if user_id not in self.users or not self.users[user_id].biometric_enabled: return {'success': False, 'error': 'Biometric not enabled for user'} # Verify device is registered if not self._is_device_registered(user_id, device_id): return {'success': False, 'error': 'Device not registered'} # Get stored biometric data stored_biometric = self.biometric_data[user_id] # Verify biometric (simulated comparison) input_hash = self._create_biometric_hash(biometric_input, user_id, device_id) if self._verify_biometric_match(input_hash, stored_biometric.biometric_hash): # Create session session_token = self._create_session(user_id, device_id) # Update last login self.users[user_id].last_login = datetime.datetime.now().isoformat() return { 'success': True, 'session_token': session_token, 'user_profile': asdict(self.users[user_id]), 'expires_in': self.app_settings['session_timeout'] } else: return {'success': False, 'error': 'Biometric verification failed'} def purchase_ticket(self, purchase_data: Dict[str, Any]) -> Dict[str, Any]: """Purchase ticket with mobile app""" user_id = purchase_data['user_id'] session_token = purchase_data['session_token'] event_id = purchase_data['event_id'] payment_method = purchase_data['payment_method'] # Verify session if not self._verify_session(user_id, session_token): return {'success': False, 'error': 'Invalid or expired session'} # Process payment (simulated) payment_result = self._process_mobile_payment(purchase_data) if not payment_result['success']: return payment_result # Create ticket ticket_data = { 'ticket_id': self._generate_ticket_id(), 'event_id': event_id, 'event_name': purchase_data.get('event_name', 'Unknown Event'), 'event_date': purchase_data.get('event_date'), 'venue': purchase_data.get('venue', 'Unknown Venue'), 'seat': purchase_data.get('seat', 'General Admission'), 'price': purchase_data['price'], 'qr_code': self._generate_qr_code(user_id, event_id), 'purchase_date': datetime.datetime.now().isoformat(), 'status': 'active' } ticket = Ticket(**ticket_data) self.tickets[user_id].append(ticket) # Store offline ticket data offline_data = self._create_offline_ticket(ticket) return { 'success': True, 'ticket': asdict(ticket), 'offline_data': offline_data, 'payment_confirmation': payment_result['transaction_id'] } def get_user_tickets(self, request_data: Dict[str, Any]) -> Dict[str, Any]: """Get user's ticket list""" user_id = request_data['user_id'] session_token = request_data['session_token'] # Verify session if not self._verify_session(user_id, session_token): return {'success': False, 'error': 'Invalid session'} user_tickets = self.tickets.get(user_id, []) # Format tickets for mobile display formatted_tickets = [] for ticket in user_tickets: formatted_tickets.append({ 'ticket_id': ticket.ticket_id, 'event_name': ticket.event_name, 'event_date': ticket.event_date, 'venue': ticket.venue, 'seat': ticket.seat, 'price': ticket.price, 'status': ticket.status, 'qr_code': ticket.qr_code, 'days_until': self._calculate_days_until(ticket.event_date) }) return { 'success': True, 'tickets': formatted_tickets, 'total_tickets': len(formatted_tickets) } def verify_ticket_qr(self, qr_data: Dict[str, Any]) -> Dict[str, Any]: """Verify ticket QR code for event entry""" qr_code = qr_data['qr_code'] event_id = qr_data['event_id'] scanner_id = qr_data['scanner_id'] # Decode QR code decoded_data = self._decode_qr_code(qr_code) if not decoded_data: return {'valid': False, 'error': 'Invalid QR code'} user_id = decoded_data['user_id'] ticket_id = decoded_data['ticket_id'] # Find ticket user_tickets = self.tickets.get(user_id, []) ticket = None for t in user_tickets: if t.ticket_id == ticket_id and t.event_id == event_id: ticket = t break if not ticket: return {'valid': False, 'error': 'Ticket not found'} if ticket.status != 'active': return {'valid': False, 'error': f'Ticket status: {ticket.status}'} # Mark ticket as used ticket.status = 'used' return { 'valid': True, 'ticket_details': { 'event_name': ticket.event_name, 'seat': ticket.seat, 'user_id': user_id }, 'entry_time': datetime.datetime.now().isoformat(), 'scanner_id': scanner_id } def _generate_user_id(self) -> str: """Generate unique user ID""" timestamp = datetime.datetime.now().isoformat() raw_string = f"USER_{timestamp}_{len(self.users)}" return hashlib.sha256(raw_string.encode()).hexdigest()[:12] def _generate_ticket_id(self) -> str: """Generate unique ticket ID""" timestamp = datetime.datetime.now().isoformat() raw_string = f"TICKET_{timestamp}_{random.random()}" return hashlib.sha256(raw_string.encode()).hexdigest()[:16] def _validate_user_data(self, user_data: Dict[str, Any]) -> bool: """Validate user registration data""" required_fields = ['email', 'phone'] return all(field in user_data for field in required_fields) def _create_biometric_hash(self, template: str, user_id: str, device_id: str) -> str: """Create biometric hash (simulated)""" combined_data = f"{template}_{user_id}_{device_id}_{datetime.datetime.now().isoformat()}" return hashlib.sha256(combined_data.encode()).hexdigest() def _verify_biometric_match(self, input_hash: str, stored_hash: str) -> bool: """Verify biometric match (simulated)""" # In real implementation, this would use sophisticated biometric matching # For demo, we'll simulate with a simple check return input_hash == stored_hash or len(input_hash) == len(stored_hash) def _register_device(self, user_id: str, device_id: str): """Register device for user""" if user_id not in self.device_registrations: self.device_registrations[user_id] = [] if device_id not in self.device_registrations[user_id]: if len(self.device_registrations[user_id]) < self.app_settings['max_devices_per_user']: self.device_registrations[user_id].append({ 'device_id': device_id, 'registered_at': datetime.datetime.now().isoformat() }) def _is_device_registered(self, user_id: str, device_id: str) -> bool: """Check if device is registered for user""" if user_id not in self.device_registrations: return False return any(device['device_id'] == device_id for device in self.device_registrations[user_id]) def _create_session(self, user_id: str, device_id: str) -> str: """Create user session""" session_token = self._generate_session_token(user_id, device_id) self.sessions[session_token] = { 'user_id': user_id, 'device_id': device_id, 'created_at': datetime.datetime.now(), 'expires_at': datetime.datetime.now() + datetime.timedelta(seconds=self.app_settings['session_timeout']) } return session_token def _generate_session_token(self, user_id: str, device_id: str) -> str: """Generate session token""" timestamp = datetime.datetime.now().isoformat() raw_string = f"SESSION_{user_id}_{device_id}_{timestamp}" return hashlib.sha256(raw_string.encode()).hexdigest()[:32] def _verify_session(self, user_id: str, session_token: str) -> bool: """Verify user session""" if session_token not in self.sessions: return False session = self.sessions[session_token] # Check user ID if session['user_id'] != user_id: return False # Check expiration if datetime.datetime.now() > session['expires_at']: del self.sessions[session_token] return False return True def _process_mobile_payment(self, payment_data: Dict[str, Any]) -> Dict[str, Any]: """Process mobile payment (simulated)""" # Simulate payment processing transaction_id = self._generate_transaction_id() return { 'success': True, 'transaction_id': transaction_id, 'amount': payment_data['price'], 'payment_method': payment_data['payment_method'] } def _generate_transaction_id(self) -> str: """Generate transaction ID""" timestamp = datetime.datetime.now().isoformat() raw_string = f"TXN_{timestamp}_{random.random()}" return hashlib.sha256(raw_string.encode()).hexdigest()[:16] def _generate_qr_code(self, user_id: str, event_id: str) -> str: """Generate QR code for ticket""" qr_data = { 'user_id': user_id, 'event_id': event_id, 'timestamp': datetime.datetime.now().isoformat(), 'ticket_id': self._generate_ticket_id() } qr_string = json.dumps(qr_data, sort_keys=True) qr_hash = hashlib.sha256(qr_string.encode()).hexdigest() # Return base64 encoded QR data (simulated) return base64.b64encode(qr_string.encode()).decode() def _decode_qr_code(self, qr_code: str) -> Optional[Dict[str, Any]]: """Decode QR code""" try: decoded_bytes = base64.b64decode(qr_code.encode()) decoded_string = decoded_bytes.decode() return json.loads(decoded_string) except: return None def _create_offline_ticket(self, ticket: Ticket) -> Dict[str, Any]: """Create offline ticket data""" return { 'ticket_id': ticket.ticket_id, 'event_name': ticket.event_name, 'event_date': ticket.event_date, 'venue': ticket.venue, 'seat': ticket.seat, 'qr_code': ticket.qr_code, 'offline_expires': (datetime.datetime.now() + datetime.timedelta(seconds=self.app_settings['offline_ticket_duration'])).isoformat(), 'signature': self._create_offline_signature(ticket) } def _create_offline_signature(self, ticket: Ticket) -> str: """Create signature for offline ticket verification""" signature_data = f"{ticket.ticket_id}_{ticket.event_id}_{ticket.qr_code}" return hashlib.sha256(signature_data.encode()).hexdigest() def _calculate_days_until(self, event_date: Optional[str]) -> int: """Calculate days until event""" if not event_date: return -1 try: event_dt = datetime.datetime.fromisoformat(event_date.replace('Z', '+00:00')) current_dt = datetime.datetime.now() return (event_dt - current_dt).days except: return -1 # Global mobile app instance mobile_app = MobileTicketingApp() def test_mobile_app(): """Test mobile ticketing app""" print("Testing Mobile Ticketing App...") # Register user user_data = { 'email': 'user@example.com', 'phone': '+1234567890' } register_result = mobile_app.register_user(user_data) print(f"User Registration: {register_result['success']}") if register_result['success']: user_id = register_result['user_id'] # Enable biometric auth biometric_data = { 'user_id': user_id, 'biometric_type': 'fingerprint', 'device_id': 'DEVICE_001', 'biometric_template': 'BIOMETRIC_TEMPLATE_123' } biometric_result = mobile_app.enable_biometric_auth(biometric_data) print(f"Biometric Setup: {biometric_result['success']}") # Authenticate auth_request = { 'user_id': user_id, 'device_id': 'DEVICE_001', 'biometric_input': 'BIOMETRIC_TEMPLATE_123' } auth_result = mobile_app.authenticate_biometric(auth_request) print(f"Biometric Auth: {auth_result['success']}") if auth_result['success']: session_token = auth_result['session_token'] # Purchase ticket purchase_data = { 'user_id': user_id, 'session_token': session_token, 'event_id': 'EVENT_CONCERT_2024', 'event_name': 'Summer Music Festival', 'event_date': '2024-07-15T20:00:00Z', 'venue': 'Madison Square Garden', 'seat': 'A-15', 'price': 150.00, 'payment_method': 'credit_card' } purchase_result = mobile_app.purchase_ticket(purchase_data) print(f"Ticket Purchase: {purchase_result['success']}") # Get user tickets tickets_request = { 'user_id': user_id, 'session_token': session_token } tickets_result = mobile_app.get_user_tickets(tickets_request) print(f"User Tickets: {len(tickets_result.get('tickets', []))}") return True if __name__ == "__main__": test_mobile_app()