# python/01-authentication.py"""Advanced authentication and authorization patterns"""fromtypingimportList,Dict,Any,Optional,Union,Tuplefromdataclassesimportdataclass,asdictfromenumimportEnumimporthashlibimporthmacimportsecretsimporttimeimportjwtfromdatetimeimportdatetime,timedeltaimportloggingfromfunctoolsimportwrapsimportbcryptimportargon2frompasslib.contextimportCryptContextimportpyotpimportqrcodefromioimportBytesIOimportbase64importasynciofromconcurrent.futuresimportThreadPoolExecutor# Configure logginglogging.basicConfig(level=logging.INFO)logger=logging.getLogger(__name__)classAuthMethod(Enum):"""Authentication method enumeration"""PASSWORD="password"TOKEN="token"OAUTH="oauth"MFA="mfa"BIOMETRIC="biometric"classPermission(Enum):"""Permission enumeration"""READ="read"WRITE="write"DELETE="delete"ADMIN="admin"@dataclassclassUser:"""User definition"""id:strusername:stremail:strpassword_hash:stris_active:bool=Trueis_verified:bool=Falsecreated_at:datetime=Nonelast_login:datetime=Nonefailed_login_attempts:int=0locked_until:datetime=Nonemfa_secret:Optional[str]=Nonepermissions:List[Permission]=Nonedef__post_init__(self):ifself.created_atisNone:self.created_at=datetime.utcnow()ifself.permissionsisNone:self.permissions=[]classPasswordManager:"""Advanced password management"""def__init__(self,algorithm:str="argon2"):self.algorithm=algorithmifalgorithm=="bcrypt":self.context=CryptContext(schemes=["bcrypt"],deprecated="auto")elifalgorithm=="argon2":self.context=CryptContext(schemes=["argon2"],deprecated="auto")else:raiseValueError(f"Unsupported algorithm: {algorithm}")defhash_password(self,password:str)->str:"""Hash password using secure algorithm"""returnself.context.hash(password)defverify_password(self,password:str,hashed:str)->bool:"""Verify password against hash"""returnself.context.verify(password,hashed)defcheck_password_strength(self,password:str)->Dict[str,Any]:"""Check password strength"""score=0feedback=[]# Length checkiflen(password)>=8:score+=1else:feedback.append("Password should be at least 8 characters long")# Character variety checksifany(c.islower()forcinpassword):score+=1else:feedback.append("Password should contain lowercase letters")ifany(c.isupper()forcinpassword):score+=1else:feedback.append("Password should contain uppercase letters")ifany(c.isdigit()forcinpassword):score+=1else:feedback.append("Password should contain numbers")ifany(cin"!@#$%^&*()_+-=[]{}|;:,.<>?"forcinpassword):score+=1else:feedback.append("Password should contain special characters")# Common password checkcommon_passwords=["password","123456","qwerty","admin"]ifpassword.lower()incommon_passwords:score=0feedback.append("Password is too common")strength_levels=["Very Weak","Weak","Fair","Good","Strong"]strength=strength_levels[min(score,4)]return{"score":score,"strength":strength,"feedback":feedback,"is_strong":score>=4}classTokenManager:"""JWT token management"""def__init__(self,secret_key:str,algorithm:str="HS256"):self.secret_key=secret_keyself.algorithm=algorithmself.token_blacklist=set()defgenerate_access_token(self,user_id:str,permissions:List[Permission],expires_in:int=3600)->str:"""Generate JWT access token"""payload={"user_id":user_id,"permissions":[p.valueforpinpermissions],"token_type":"access","exp":datetime.utcnow()+timedelta(seconds=expires_in),"iat":datetime.utcnow(),"jti":secrets.token_urlsafe(32)# JWT ID for blacklisting}returnjwt.encode(payload,self.secret_key,algorithm=self.algorithm)defgenerate_refresh_token(self,user_id:str,expires_in:int=86400*7)->str:"""Generate JWT refresh token"""payload={"user_id":user_id,"token_type":"refresh","exp":datetime.utcnow()+timedelta(seconds=expires_in),"iat":datetime.utcnow(),"jti":secrets.token_urlsafe(32)}returnjwt.encode(payload,self.secret_key,algorithm=self.algorithm)defverify_token(self,token:str)->Optional[Dict[str,Any]]:"""Verify and decode JWT token"""try:# Check if token is blacklistediftokeninself.token_blacklist:returnNonepayload=jwt.decode(token,self.secret_key,algorithms=[self.algorithm])returnpayloadexceptjwt.ExpiredSignatureError:logger.warning("Token has expired")returnNoneexceptjwt.InvalidTokenError:logger.warning("Invalid token")returnNonedefblacklist_token(self,token:str)->None:"""Add token to blacklist"""self.token_blacklist.add(token)defrefresh_access_token(self,refresh_token:str)->Optional[str]:"""Generate new access token from refresh token"""payload=self.verify_token(refresh_token)ifnotpayloadorpayload.get("token_type")!="refresh":returnNone# Generate new access tokenuser_id=payload["user_id"]permissions=[Permission(p)forpinpayload.get("permissions",[])]returnself.generate_access_token(user_id,permissions)classMFAManager:"""Multi-Factor Authentication manager"""def__init__(self):self.totp=pyotp.TOTPdefgenerate_mfa_secret(self,user_id:str)->str:"""Generate MFA secret for user"""secret=pyotp.random_base32()returnsecretdefgenerate_mfa_qr_code(self,user_id:str,secret:str,issuer:str="MyApp")->str:"""Generate QR code for MFA setup"""totp_uri=pyotp.totp.TOTP(secret).provisioning_uri(name=user_id,issuer_name=issuer)qr=qrcode.QRCode(version=1,box_size=10,border=5)qr.add_data(totp_uri)qr.make(fit=True)img=qr.make_image(fill_color="black",back_color="white")# Convert to base64buffer=BytesIO()img.save(buffer,format='PNG')img_str=base64.b64encode(buffer.getvalue()).decode()returnf"data:image/png;base64,{img_str}"defverify_mfa_code(self,secret:str,code:str)->bool:"""Verify MFA code"""totp=pyotp.TOTP(secret)returntotp.verify(code,valid_window=1)defgenerate_backup_codes(self,count:int=10)->List[str]:"""Generate backup codes for MFA"""return[secrets.token_urlsafe(8)for_inrange(count)]classRateLimiter:"""Rate limiting for authentication"""def__init__(self,max_attempts:int=5,window_minutes:int=15):self.max_attempts=max_attemptsself.window_minutes=window_minutesself.attempts={}# {ip: [(timestamp, success), ...]}defis_rate_limited(self,ip:str)->bool:"""Check if IP is rate limited"""now=datetime.utcnow()window_start=now-timedelta(minutes=self.window_minutes)ifipnotinself.attempts:returnFalse# Filter attempts within windowrecent_attempts=[attemptforattemptinself.attempts[ip]ifattempt[0]>window_start]# Count failed attemptsfailed_attempts=[attemptforattemptinrecent_attemptsifnotattempt[1]]returnlen(failed_attempts)>=self.max_attemptsdefrecord_attempt(self,ip:str,success:bool)->None:"""Record authentication attempt"""now=datetime.utcnow()ifipnotinself.attempts:self.attempts[ip]=[]self.attempts[ip].append((now,success))# Clean old attemptswindow_start=now-timedelta(minutes=self.window_minutes*2)self.attempts[ip]=[attemptforattemptinself.attempts[ip]ifattempt[0]>window_start]classAuthenticationService:"""Comprehensive authentication service"""def__init__(self,password_manager:PasswordManager,token_manager:TokenManager,mfa_manager:MFAManager,rate_limiter:RateLimiter):self.password_manager=password_managerself.token_manager=token_managerself.mfa_manager=mfa_managerself.rate_limiter=rate_limiterself.users={}# In production, this would be a databaseself.sessions={}defregister_user(self,username:str,email:str,password:str)->Dict[str,Any]:"""Register new user"""# Check password strengthstrength_check=self.password_manager.check_password_strength(password)ifnotstrength_check["is_strong"]:return{"success":False,"error":"Password is not strong enough","feedback":strength_check["feedback"]}# Check if user already existsifusernameinself.usersoremailin[user.emailforuserinself.users.values()]:return{"success":False,"error":"User already exists"}# Create useruser=User(id=secrets.token_urlsafe(16),username=username,email=email,password_hash=self.password_manager.hash_password(password))self.users[username]=userreturn{"success":True,"user_id":user.id,"message":"User registered successfully"}defauthenticate_user(self,username:str,password:str,mfa_code:Optional[str]=None,ip:str="unknown")->Dict[str,Any]:"""Authenticate user with optional MFA"""# Check rate limitingifself.rate_limiter.is_rate_limited(ip):return{"success":False,"error":"Too many failed attempts. Please try again later."}# Check if user existsifusernamenotinself.users:self.rate_limiter.record_attempt(ip,False)return{"success":False,"error":"Invalid credentials"}user=self.users[username]# Check if user is lockedifuser.locked_untilanddatetime.utcnow()<user.locked_until:return{"success":False,"error":"Account is locked"}# Verify passwordifnotself.password_manager.verify_password(password,user.password_hash):user.failed_login_attempts+=1# Lock account after too many failed attemptsifuser.failed_login_attempts>=5:user.locked_until=datetime.utcnow()+timedelta(minutes=30)self.rate_limiter.record_attempt(ip,False)return{"success":False,"error":"Invalid credentials"}# Check MFA if enabledifuser.mfa_secret:ifnotmfa_code:return{"success":False,"error":"MFA code required","mfa_required":True}ifnotself.mfa_manager.verify_mfa_code(user.mfa_secret,mfa_code):self.rate_limiter.record_attempt(ip,False)return{"success":False,"error":"Invalid MFA code"}# Reset failed attemptsuser.failed_login_attempts=0user.locked_until=Noneuser.last_login=datetime.utcnow()# Generate tokensaccess_token=self.token_manager.generate_access_token(user.id,user.permissions)refresh_token=self.token_manager.generate_refresh_token(user.id)# Store sessionsession_id=secrets.token_urlsafe(32)self.sessions[session_id]={"user_id":user.id,"created_at":datetime.utcnow(),"ip":ip}self.rate_limiter.record_attempt(ip,True)return{"success":True,"access_token":access_token,"refresh_token":refresh_token,"session_id":session_id,"user":{"id":user.id,"username":user.username,"email":user.email,"permissions":[p.valueforpinuser.permissions]}}defsetup_mfa(self,username:str)->Dict[str,Any]:"""Setup MFA for user"""ifusernamenotinself.users:return{"success":False,"error":"User not found"}user=self.users[username]secret=self.mfa_manager.generate_mfa_secret(user.id)user.mfa_secret=secretqr_code=self.mfa_manager.generate_mfa_qr_code(user.id,secret)backup_codes=self.mfa_manager.generate_backup_codes()return{"success":True,"secret":secret,"qr_code":qr_code,"backup_codes":backup_codes}defverify_token(self,token:str)->Optional[Dict[str,Any]]:"""Verify JWT token"""returnself.token_manager.verify_token(token)deflogout(self,token:str)->bool:"""Logout user and blacklist token"""self.token_manager.blacklist_token(token)returnTrueclassAuthorizationService:"""Authorization service for permission checking"""def__init__(self,auth_service:AuthenticationService):self.auth_service=auth_servicedefcheck_permission(self,token:str,required_permission:Permission)->bool:"""Check if user has required permission"""payload=self.auth_service.verify_token(token)ifnotpayload:returnFalseuser_permissions=[Permission(p)forpinpayload.get("permissions",[])]returnrequired_permissioninuser_permissionsdefrequire_permission(self,permission:Permission):"""Decorator to require specific permission"""defdecorator(func):@wraps(func)defwrapper(*args,**kwargs):# Extract token from request (implementation depends on framework)token=kwargs.get('token')orargs[0]ifargselseNoneifnottokenornotself.check_permission(token,permission):raisePermissionError("Insufficient permissions")returnfunc(*args,**kwargs)returnwrapperreturndecorator# Usage examplesdefexample_authentication():"""Example authentication usage"""# Create managerspassword_manager=PasswordManager("argon2")token_manager=TokenManager("your-secret-key")mfa_manager=MFAManager()rate_limiter=RateLimiter()# Create authentication serviceauth_service=AuthenticationService(password_manager,token_manager,mfa_manager,rate_limiter)# Register userregistration_result=auth_service.register_user("john_doe","john@example.com","SecurePassword123!")print(f"Registration: {registration_result}")# Authenticate userauth_result=auth_service.authenticate_user("john_doe","SecurePassword123!")print(f"Authentication: {auth_result}")# Setup MFAmfa_result=auth_service.setup_mfa("john_doe")print(f"MFA setup: {mfa_result['success']}")# Verify tokenifauth_result["success"]:token_payload=auth_service.verify_token(auth_result["access_token"])print(f"Token payload: {token_payload}")# Authorizationauthz_service=AuthorizationService(auth_service)@authz_service.require_permission(Permission.READ)defread_data(token:str):return"Data read successfully"# Test authorizationtry:result=read_data(auth_result["access_token"])print(f"Authorization test: {result}")exceptPermissionErrorase:print(f"Authorization failed: {e}")
# python/02-input-validation.py"""Input validation and sanitization patterns"""fromtypingimportList,Dict,Any,Optional,Union,Tupleimportreimporthtmlimportbleachimportvalidatorsfromemail_validatorimportvalidate_email,EmailNotValidErrorimportphonenumbersfromphonenumbersimportNumberParseExceptionimportuuidfromdatetimeimportdatetimeimportjsonimportloggingfromdataclassesimportdataclassfromenumimportEnumimportasynciofromconcurrent.futuresimportThreadPoolExecutorlogger=logging.getLogger(__name__)classValidationError(Exception):"""Custom validation error"""passclassInputValidator:"""Comprehensive input validator"""def__init__(self):self.validation_rules={}self.sanitization_rules={}defvalidate_string(self,value:str,min_length:int=0,max_length:int=1000,pattern:Optional[str]=None,allow_html:bool=False)->str:"""Validate and sanitize string input"""ifnotisinstance(value,str):raiseValidationError("Value must be a string")# Length validationiflen(value)<min_length:raiseValidationError(f"String too short (minimum {min_length} characters)")iflen(value)>max_length:raiseValidationError(f"String too long (maximum {max_length} characters)")# Pattern validationifpatternandnotre.match(pattern,value):raiseValidationError("String does not match required pattern")# HTML sanitizationifnotallow_html:value=html.escape(value)returnvaluedefvalidate_email(self,email:str)->str:"""Validate email address"""try:validated_email=validate_email(email)returnvalidated_email.emailexceptEmailNotValidErrorase:raiseValidationError(f"Invalid email address: {e}")defvalidate_phone(self,phone:str,country_code:str="US")->str:"""Validate phone number"""try:parsed_number=phonenumbers.parse(phone,country_code)ifnotphonenumbers.is_valid_number(parsed_number):raiseValidationError("Invalid phone number")returnphonenumbers.format_number(parsed_number,phonenumbers.PhoneNumberFormat.E164)exceptNumberParseExceptionase:raiseValidationError(f"Invalid phone number: {e}")defvalidate_url(self,url:str)->str:"""Validate URL"""ifnotvalidators.url(url):raiseValidationError("Invalid URL")returnurldefvalidate_uuid(self,uuid_string:str)->str:"""Validate UUID"""try:uuid.UUID(uuid_string)returnuuid_stringexceptValueError:raiseValidationError("Invalid UUID format")defvalidate_json(self,json_string:str)->Dict[str,Any]:"""Validate JSON string"""try:returnjson.loads(json_string)exceptjson.JSONDecodeErrorase:raiseValidationError(f"Invalid JSON: {e}")defvalidate_integer(self,value:Union[str,int],min_value:Optional[int]=None,max_value:Optional[int]=None)->int:"""Validate integer"""try:int_value=int(value)except(ValueError,TypeError):raiseValidationError("Value must be an integer")ifmin_valueisnotNoneandint_value<min_value:raiseValidationError(f"Value must be at least {min_value}")ifmax_valueisnotNoneandint_value>max_value:raiseValidationError(f"Value must be at most {max_value}")returnint_valuedefvalidate_float(self,value:Union[str,float],min_value:Optional[float]=None,max_value:Optional[float]=None)->float:"""Validate float"""try:float_value=float(value)except(ValueError,TypeError):raiseValidationError("Value must be a float")ifmin_valueisnotNoneandfloat_value<min_value:raiseValidationError(f"Value must be at least {min_value}")ifmax_valueisnotNoneandfloat_value>max_value:raiseValidationError(f"Value must be at most {max_value}")returnfloat_valuedefvalidate_boolean(self,value:Union[str,bool])->bool:"""Validate boolean"""ifisinstance(value,bool):returnvalueifisinstance(value,str):ifvalue.lower()in('true','1','yes','on'):returnTrueelifvalue.lower()in('false','0','no','off'):returnFalseraiseValidationError("Value must be a boolean")defvalidate_datetime(self,value:Union[str,datetime],format_string:Optional[str]=None)->datetime:"""Validate datetime"""ifisinstance(value,datetime):returnvalueifisinstance(value,str):ifformat_string:try:returndatetime.strptime(value,format_string)exceptValueError:raiseValidationError(f"Invalid datetime format. Expected: {format_string}")else:# Try common formatsformats=["%Y-%m-%d %H:%M:%S","%Y-%m-%dT%H:%M:%S","%Y-%m-%dT%H:%M:%SZ","%Y-%m-%d"]forfmtinformats:try:returndatetime.strptime(value,fmt)exceptValueError:continueraiseValidationError("Invalid datetime format")raiseValidationError("Value must be a datetime")classSQLInjectionPrevention:"""SQL injection prevention utilities"""@staticmethoddefsanitize_sql_input(value:str)->str:"""Sanitize input for SQL queries"""# Remove or escape dangerous charactersdangerous_chars=["'",'"',";","--","/*","*/","xp_","sp_"]forcharindangerous_chars:value=value.replace(char,"")# Limit lengthiflen(value)>1000:value=value[:1000]returnvalue@staticmethoddefvalidate_sql_identifier(identifier:str)->bool:"""Validate SQL identifier (table/column name)"""# Only allow alphanumeric characters and underscorespattern=r'^[a-zA-Z_][a-zA-Z0-9_]*$'returnbool(re.match(pattern,identifier))classXSSPrevention:"""XSS prevention utilities"""@staticmethoddefsanitize_html(html_content:str,allowed_tags:List[str]=None)->str:"""Sanitize HTML content"""ifallowed_tagsisNone:allowed_tags=['p','br','strong','em','u']returnbleach.clean(html_content,tags=allowed_tags)@staticmethoddefescape_html(text:str)->str:"""Escape HTML characters"""returnhtml.escape(text)@staticmethoddefvalidate_css(css_content:str)->str:"""Validate and sanitize CSS content"""# Remove dangerous CSS propertiesdangerous_properties=['expression','javascript:','vbscript:','onload','onerror']forpropindangerous_properties:css_content=css_content.replace(prop,"")returncss_contentclassFileUploadValidator:"""File upload validation"""def__init__(self,max_size:int=10*1024*1024,# 10MBallowed_extensions:List[str]=None,allowed_mime_types:List[str]=None):self.max_size=max_sizeself.allowed_extensions=allowed_extensionsor['.jpg','.jpeg','.png','.gif','.pdf']self.allowed_mime_types=allowed_mime_typesor['image/jpeg','image/png','image/gif','application/pdf']defvalidate_file(self,filename:str,content:bytes,mime_type:str)->Dict[str,Any]:"""Validate uploaded file"""errors=[]# Check file sizeiflen(content)>self.max_size:errors.append(f"File too large (maximum {self.max_size} bytes)")# Check file extensionfile_ext='.'+filename.split('.')[-1].lower()iffile_extnotinself.allowed_extensions:errors.append(f"File extension not allowed: {file_ext}")# Check MIME typeifmime_typenotinself.allowed_mime_types:errors.append(f"MIME type not allowed: {mime_type}")# Check for malicious contentifself._contains_malicious_content(content):errors.append("File contains potentially malicious content")return{"valid":len(errors)==0,"errors":errors,"size":len(content),"extension":file_ext,"mime_type":mime_type}def_contains_malicious_content(self,content:bytes)->bool:"""Check for malicious content in file"""# Check for executable signaturesexecutable_signatures=[b'MZ',# PE executableb'\x7fELF',# ELF executableb'\xfe\xed\xfa',# Mach-O executable]forsignatureinexecutable_signatures:ifcontent.startswith(signature):returnTrue# Check for script tags in text filesifb'<script'incontent.lower():returnTruereturnFalseclassInputSanitizer:"""Comprehensive input sanitizer"""def__init__(self):self.validator=InputValidator()self.sql_prevention=SQLInjectionPrevention()self.xss_prevention=XSSPrevention()self.file_validator=FileUploadValidator()defsanitize_user_input(self,data:Dict[str,Any])->Dict[str,Any]:"""Sanitize user input data"""sanitized_data={}forkey,valueindata.items():try:# Sanitize keysanitized_key=self.sql_prevention.sanitize_sql_input(key)# Sanitize value based on typeifisinstance(value,str):# Basic string sanitizationsanitized_value=self.xss_prevention.escape_html(value)sanitized_value=self.sql_prevention.sanitize_sql_input(sanitized_value)elifisinstance(value,dict):# Recursively sanitize nested dictionariessanitized_value=self.sanitize_user_input(value)elifisinstance(value,list):# Sanitize list itemssanitized_value=[self.sanitize_user_input(item)ifisinstance(item,dict)elseself.xss_prevention.escape_html(str(item))foriteminvalue]else:sanitized_value=valuesanitized_data[sanitized_key]=sanitized_valueexceptExceptionase:logger.error(f"Error sanitizing input {key}: {e}")sanitized_data[key]=""# Default to empty string for safetyreturnsanitized_datadefvalidate_and_sanitize(self,data:Dict[str,Any],validation_rules:Dict[str,Dict[str,Any]])->Dict[str,Any]:"""Validate and sanitize input according to rules"""sanitized_data={}validation_errors={}forfield,rulesinvalidation_rules.items():iffieldnotindata:ifrules.get('required',False):validation_errors[field]="Field is required"continuetry:value=data[field]# Apply validation rulesifrules.get('type')=='string':value=self.validator.validate_string(value,min_length=rules.get('min_length',0),max_length=rules.get('max_length',1000),pattern=rules.get('pattern'),allow_html=rules.get('allow_html',False))elifrules.get('type')=='email':value=self.validator.validate_email(value)elifrules.get('type')=='integer':value=self.validator.validate_integer(value,min_value=rules.get('min_value'),max_value=rules.get('max_value'))elifrules.get('type')=='boolean':value=self.validator.validate_boolean(value)# Apply sanitizationifisinstance(value,str):value=self.xss_prevention.escape_html(value)value=self.sql_prevention.sanitize_sql_input(value)sanitized_data[field]=valueexceptValidationErrorase:validation_errors[field]=str(e)exceptExceptionase:validation_errors[field]=f"Validation error: {e}"return{"data":sanitized_data,"errors":validation_errors,"valid":len(validation_errors)==0}# Usage examplesdefexample_input_validation():"""Example input validation usage"""# Create sanitizersanitizer=InputSanitizer()# Validate user inputuser_data={"username":"john_doe","email":"john@example.com","age":"25","bio":"<script>alert('xss')</script>Hello World!"}validation_rules={"username":{"type":"string","min_length":3,"max_length":50,"pattern":r"^[a-zA-Z0-9_]+$"},"email":{"type":"email","required":True},"age":{"type":"integer","min_value":18,"max_value":100},"bio":{"type":"string","max_length":500,"allow_html":False}}result=sanitizer.validate_and_sanitize(user_data,validation_rules)print(f"Validation result: {result}")# File upload validationfile_content=b"fake image content"file_validation=sanitizer.file_validator.validate_file("test.jpg",file_content,"image/jpeg")print(f"File validation: {file_validation}")# SQL injection preventionsql_input="'; DROP TABLE users; --"sanitized_sql=sanitizer.sql_prevention.sanitize_sql_input(sql_input)print(f"SQL sanitization: {sanitized_sql}")# XSS preventionhtml_content="<script>alert('xss')</script><p>Safe content</p>"sanitized_html=sanitizer.xss_prevention.sanitize_html(html_content)print(f"HTML sanitization: {sanitized_html}")