บทนำ: ทำไมต้อง Model Privacy?
เมื่อเรารู้เรื่อง private, public, getter/setter, static แล้ว
คำถามต่อไป: เราควรออกแบบระบบอย่างไรให้ปลอดภัย?
text❓ ตัวอย่างสถานการณ์:
1. ข้อมูลตัวบุคคล (ชื่อ, ID, ที่อยู่)
- ใครควร** access ได้?
2. ข้อมูลการเงิน (password, credit card)
- ควร**เก็บอย่างไร** ให้ปลอดภัย?
3. ข้อมูลระบบ (configuration, logs)
- ใครควรมี**สิทธิ์ดู**?
ยาวไปอยากเลือกอ่าน
- บทนำ: ทำไมต้อง Model Privacy?
- หลักการ 3 ประการของ Data Privacy
- 1. Confidentiality: เก็บเป็นความลับ
- ❌ ไม่ปลอดภัย: เปิดเผยข้อมูลสำคัญ
- ✓ ปลอดภัย: ซ่อนข้อมูลสำคัญ
- 2. Integrity: ข้อมูลต้องถูกต้อง
- ❌ ไม่ปลอดภัย: ใครก็เปลี่ยนข้อมูลได้
- ✓ ปลอดภัย: Validation ก่อนเปลี่ยน
- 3. Availability: ข้อมูลต้องสำหรับเข้าถึงเมื่อต้องการ
- ❌ ไม่ปลอดภัย: เข้าถึงไม่ได้
- ✓ ปลอดภัย: ให้เข้าถึงได้อย่างปลอดภัย
- Data Classification: จำแนกข้อมูล
- ขั้นที่ 1: ระบุข้อมูลที่ต้องปกป้อง
- ตัวอย่างที่ 1: Classify Employee Data
- Role-Based Access Control (RBAC)
- หลักการ: ตัดสินใจเข้าถึงตามบทบาท
- ตัวอย่างที่ 2: Document System ด้วย RBAC
- Sensitive Data: ต้องการการปกป้องพิเศษ
- ตัวอย่างที่ 3: Password Security
- ตัวอย่างที่ 4: Credit Card Security
- Security Best Practices
- 1. Principle of Least Privilege (PoLP)
- 2. Defense in Depth
- ตัวอย่างที่ 5: Banking System ด้วย Multiple Security Layers
- Data Privacy Checklist
- ตรวจสอบก่อนเขียน Code
- สรุป: Modeling Data Privacy
- ตัวอย่างสุดท้าย: Medical Records System
หลักการ 3 ประการของ Data Privacy
1. Confidentiality: เก็บเป็นความลับ
Confidentiality = ข้อมูลสำคัญ ต้องซ่อนไว้ ไม่ให้คนที่ไม่ควรเห็น
❌ ไม่ปลอดภัย: เปิดเผยข้อมูลสำคัญ
javapublic class User {
public String username;
public String password; // ❌ ใครก็ดูได้!
public String creditCardNumber; // ❌ ใครก็ดูได้!
public String ssn; // ❌ ใครก็ดูได้! (Social Security)
}
// Hacker สามารถเข้าถึงได้ง่าย
User user = new User();
String stealPassword = user.password; // ❌ Exposed!
String stealCard = user.creditCardNumber; // ❌ Stolen!
✓ ปลอดภัย: ซ่อนข้อมูลสำคัญ
javapublic class User {
private String username;
private String password; // ← ซ่อน
private String creditCardNumber; // ← ซ่อน
private String ssn; // ← ซ่อน
// ✓ เข้าถึงผ่าน method ที่ควบคุม
public boolean verifyPassword(String input) {
return password.equals(input); // ✓ เฉพาะ verify
}
public boolean verifyCard(String input) {
return creditCardNumber.equals(input);
}
// ❌ ไม่มี getPassword(), getCardNumber()
}
// ใช้งาน: ไม่ได้อ่านข้อมูลจริง
if (user.verifyPassword("myPassword")) {
System.out.println("✓ Password correct");
}
// ❌ ไม่สามารถ:
// String password = user.password; // ERROR! private
// String card = user.creditCardNumber; // ERROR! private
2. Integrity: ข้อมูลต้องถูกต้อง
Integrity = ข้อมูลต้องถูกต้องและสมบูรณ์ ไม่ถูกแก้ไขแบบผิดๆ
❌ ไม่ปลอดภัย: ใครก็เปลี่ยนข้อมูลได้
javapublic class Account {
public double balance; // ❌ ใครก็เปลี่ยนได้
}
// Hacker เปลี่ยนข้อมูล
Account myAccount = new Account();
myAccount.balance = 1000;
myAccount.balance = 999999999; // ❌ ยัง set ได้! Invalid!
myAccount.balance = -5000; // ❌ ยัง set ได้! Invalid!
✓ ปลอดภัย: Validation ก่อนเปลี่ยน
javapublic class Account {
private double balance; // ← ซ่อน
// ✓ Setter มี validation
public void setBalance(double newBalance) {
if (newBalance < 0) {
throw new IllegalArgumentException("Balance cannot be negative");
}
this.balance = newBalance;
}
public void withdraw(double amount) {
if (amount > this.balance) {
throw new IllegalArgumentException("Insufficient balance");
}
this.balance -= amount;
}
}
// ใช้งาน: ข้อมูลถูกต้องเสมอ
Account account = new Account();
account.setBalance(1000);
account.setBalance(-5000); // ❌ ERROR! "Balance cannot be negative"
account.withdraw(99999); // ❌ ERROR! "Insufficient balance"
3. Availability: ข้อมูลต้องสำหรับเข้าถึงเมื่อต้องการ
Availability = ข้อมูลถูกต้อง ต้องสามารถ access ได้เมื่อต้องการ
❌ ไม่ปลอดภัย: เข้าถึงไม่ได้
javapublic class CriticalData {
private String apiKey; // ← ซ่อนไป
// ❌ ไม่มี method ให้เข้าถึง
// ไม่มี getApiKey()
// ไม่มี verifyKey()
}
// Application ไม่สามารถใช้ได้
CriticalData data = new CriticalData();
// String key = data.getApiKey(); // ERROR! No such method
✓ ปลอดภัย: ให้เข้าถึงได้อย่างปลอดภัย
javapublic class CriticalData {
private String apiKey;
// ✓ Getter ที่ปลอดภัย
public boolean verifyApiKey(String inputKey) {
return apiKey.equals(inputKey);
}
public String getApiKeyForAuthorizedUser(String role) {
if ("ADMIN".equals(role)) {
return apiKey; // ✓ เฉพาะ ADMIN
}
throw new SecurityException("Unauthorized access");
}
}
// ใช้งาน: บัญชี admin ถึง access ได้
CriticalData data = new CriticalData();
// ✓ Verify (ใครก็ได้)
if (data.verifyApiKey("secret-key-123")) {
System.out.println("✓ Key is correct");
}
// ✓ Get (เฉพาะ ADMIN)
try {
String key = data.getApiKeyForAuthorizedUser("ADMIN");
System.out.println("Key retrieved for admin");
} catch (SecurityException e) {
System.out.println("Error: " + e.getMessage());
}
Data Classification: จำแนกข้อมูล
ขั้นที่ 1: ระบุข้อมูลที่ต้องปกป้อง
text┌─────────────────────────────────────────────────┐
│ Data Classification Framework │
├─────────────────────────────────────────────────┤
│ │
│ PUBLIC (ข้อมูลสาธารณะ) │
│ ├─ ใครก็ดูได้ │
│ └─ เช่น: Product catalog, Public announcements
│ │
│ INTERNAL (ข้อมูลภายใน) │
│ ├─ เฉพาะ employees │
│ └─ เช่น: Company policies, Meeting notes │
│ │
│ CONFIDENTIAL (ข้อมูลลับ) │
│ ├─ เฉพาะ authorized personnel │
│ └─ เช่น: Salary info, Trade secrets │
│ │
│ RESTRICTED (ข้อมูลอันตราย) │
│ ├─ เฉพาะ executives/authorized │
│ └─ เช่น: Financial records, Security keys │
│ │
└─────────────────────────────────────────────────┘
ตัวอย่างที่ 1: Classify Employee Data
javapublic class Employee {
// PUBLIC - ใครก็ดูได้
private String name;
private String department;
// INTERNAL - เฉพาะ HR/Manager
private String email;
private String phoneNumber;
// CONFIDENTIAL - เฉพาะ HR
private double salary;
private String ssn;
// RESTRICTED - เฉพาะ CEO/CFO
private String bankAccount;
private double performanceBonus;
// ===== GETTERS: Classified Access =====
// PUBLIC - ใครก็เข้าถึงได้
public String getName() {
return this.name;
}
public String getDepartment() {
return this.department;
}
// INTERNAL - เฉพาะ HR role
public String getEmailByRole(String role) {
if ("HR".equals(role) || "MANAGER".equals(role)) {
return this.email;
}
throw new SecurityException("Unauthorized");
}
// CONFIDENTIAL - เฉพาะ HR role
public double getSalaryByRole(String role) {
if ("HR".equals(role)) {
return this.salary;
}
throw new SecurityException("Unauthorized");
}
// RESTRICTED - เฉพาะ FINANCE role
public double getPerformanceBonusByRole(String role) {
if ("FINANCE".equals(role) || "CEO".equals(role)) {
return this.performanceBonus;
}
throw new SecurityException("Unauthorized");
}
}
Role-Based Access Control (RBAC)
หลักการ: ตัดสินใจเข้าถึงตามบทบาท
text┌─────────────────────────────────────────┐
│ Role-Based Access Control (RBAC) │
├─────────────────────────────────────────┤
│ │
│ User ──→ Role ──→ Permissions │
│ │
│ John (ADMIN) ──→ Full access │
│ Jane (USER) ──→ Limited access │
│ Bob (GUEST) ──→ Read-only access │
│ │
└─────────────────────────────────────────┘
ตัวอย่างที่ 2: Document System ด้วย RBAC
javapublic class Document {
private String documentID;
private String title;
private String content;
private String classification; // "PUBLIC", "INTERNAL", "CONFIDENTIAL"
private String owner;
public Document(String id, String title, String content, String classification) {
this.documentID = id;
this.title = title;
this.content = content;
this.classification = classification;
}
// ===== Access Control =====
public String getContent(User user) {
// Check permission based on user's role
if (canAccess(user)) {
return this.content;
}
throw new SecurityException("Access denied for " + user.getRole());
}
private boolean canAccess(User user) {
String userRole = user.getRole();
// PUBLIC - ทุกคน
if ("PUBLIC".equals(this.classification)) {
return true;
}
// INTERNAL - เฉพาะ EMPLOYEE และขึ้นไป
if ("INTERNAL".equals(this.classification)) {
return "EMPLOYEE".equals(userRole) ||
"MANAGER".equals(userRole) ||
"ADMIN".equals(userRole);
}
// CONFIDENTIAL - เฉพาะ MANAGER, ADMIN
if ("CONFIDENTIAL".equals(this.classification)) {
return "MANAGER".equals(userRole) || "ADMIN".equals(userRole);
}
// Owner สามารถเข้าถึงทุก classification
if (this.owner.equals(user.getUserID())) {
return true;
}
return false;
}
public void displayTitle() {
System.out.println("Doc: " + this.title);
}
}
public class User {
private String userID;
private String role; // "GUEST", "EMPLOYEE", "MANAGER", "ADMIN"
public User(String id, String role) {
this.userID = id;
this.role = role;
}
public String getRole() {
return this.role;
}
public String getUserID() {
return this.userID;
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
// สร้าง documents
Document publicDoc = new Document("DOC1", "Public Policy",
"This is public", "PUBLIC");
Document internalDoc = new Document("DOC2", "Company Strategy",
"Secret strategy", "INTERNAL");
Document confidentialDoc = new Document("DOC3", "Financial Report",
"Q4 earnings: $1M", "CONFIDENTIAL");
// สร้าง users
User guest = new User("U1", "GUEST");
User employee = new User("U2", "EMPLOYEE");
User manager = new User("U3", "MANAGER");
User admin = new User("U4", "ADMIN");
System.out.println("=== Public Document ===");
publicDoc.displayTitle();
System.out.println("Guest: " + tryReadDocument(publicDoc, guest));
System.out.println("Employee: " + tryReadDocument(publicDoc, employee));
System.out.println("\n=== Internal Document ===");
internalDoc.displayTitle();
System.out.println("Guest: " + tryReadDocument(internalDoc, guest));
System.out.println("Employee: " + tryReadDocument(internalDoc, employee));
System.out.println("Manager: " + tryReadDocument(internalDoc, manager));
System.out.println("\n=== Confidential Document ===");
confidentialDoc.displayTitle();
System.out.println("Employee: " + tryReadDocument(confidentialDoc, employee));
System.out.println("Manager: " + tryReadDocument(confidentialDoc, manager));
System.out.println("Admin: " + tryReadDocument(confidentialDoc, admin));
}
private static String tryReadDocument(Document doc, User user) {
try {
String content = doc.getContent(user);
return "✓ Read: " + content.substring(0, 20) + "...";
} catch (SecurityException e) {
return "❌ " + e.getMessage();
}
}
}
Output:
text=== Public Document ===
Doc: Public Policy
Guest: ✓ Read: This is public...
Employee: ✓ Read: This is public...
=== Internal Document ===
Doc: Company Strategy
Guest: ❌ Access denied for GUEST
Employee: ✓ Read: Secret strategy...
Manager: ✓ Read: Secret strategy...
=== Confidential Document ===
Doc: Financial Report
Employee: ❌ Access denied for EMPLOYEE
Manager: ✓ Read: Q4 earnings: $1M...
Admin: ✓ Read: Q4 earnings: $1M...
Sensitive Data: ต้องการการปกป้องพิเศษ
ตัวอย่างที่ 3: Password Security
javapublic class SecurePassword {
// ❌ ไม่ปลอดภัย: เก็บ password ตรงๆ
// private String password = "myPassword123";
// ✓ ปลอดภัย: Hash password
private String passwordHash;
public SecurePassword(String plainPassword) {
// Hash password ตอน initialize
this.passwordHash = hashPassword(plainPassword);
}
// ✓ Verify เฉพาะ - ไม่ return password
public boolean verifyPassword(String inputPassword) {
String inputHash = hashPassword(inputPassword);
return passwordHash.equals(inputHash);
}
// ✓ ไม่มี getPassword() method
// Password ไม่ควรส่ง out
public void changePassword(String oldPassword, String newPassword) {
// Verify old password ก่อน
if (!verifyPassword(oldPassword)) {
throw new SecurityException("Old password is incorrect");
}
// Hash และ update
this.passwordHash = hashPassword(newPassword);
System.out.println("✓ Password changed successfully");
}
// Simple hash function (in real: use bcrypt, scrypt, argon2)
private String hashPassword(String password) {
return Integer.toHexString(password.hashCode());
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
SecurePassword password = new SecurePassword("MySecurePass123");
// ✓ Verify ได้
System.out.println("Correct password: " +
password.verifyPassword("MySecurePass123"));
System.out.println("Wrong password: " +
password.verifyPassword("WrongPassword"));
// ✓ Change password ด้วยการ verify old password
password.changePassword("MySecurePass123", "NewPass456");
System.out.println("New password works: " +
password.verifyPassword("NewPass456"));
}
}
ตัวอย่างที่ 4: Credit Card Security
javapublic class CreditCard {
// ❌ ไม่ปลอดภัย: เก็บ card number ทั้งหมด
// private String cardNumber = "1234-5678-9012-3456";
// ✓ ปลอดภัย: เก็บแค่ส่วนท้าย + masked display
private String lastFourDigits;
private String cardNumberEncrypted; // encrypted
private String cvvHashed; // hashed (never store plain)
private String expiryDate;
public CreditCard(String cardNumber, String cvv, String expiry) {
this.lastFourDigits = cardNumber.substring(cardNumber.length() - 4);
this.cardNumberEncrypted = encryptCardNumber(cardNumber);
this.cvvHashed = hashCVV(cvv);
this.expiryDate = expiry;
}
// ✓ ไม่ return card number
public String getDisplayNumber() {
return "****-****-****-" + lastFourDigits;
}
// ✓ Verify CVV เฉพาะ
public boolean verifyCVV(String inputCVV) {
return cvvHashed.equals(hashCVV(inputCVV));
}
// ✓ Process payment แบบ secure
public boolean processPayment(String amount, String cvv) {
// 1. Verify CVV
if (!verifyCVV(cvv)) {
throw new SecurityException("Invalid CVV");
}
// 2. Check expiry
if (isExpired()) {
throw new SecurityException("Card expired");
}
// 3. Process with encrypted card number
return processWithEncryptedCard(cardNumberEncrypted, amount);
}
private boolean isExpired() {
// Check expiry date
return false; // Simplified
}
private boolean processWithEncryptedCard(String encrypted, String amount) {
System.out.println("✓ Processing payment: " + amount + " with card " +
getDisplayNumber());
return true;
}
private String encryptCardNumber(String number) {
return "ENCRYPTED_" + number.hashCode();
}
private String hashCVV(String cvv) {
return Integer.toHexString(cvv.hashCode());
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
CreditCard card = new CreditCard("1234-5678-9012-3456", "123", "12/25");
// ✓ Display masked number
System.out.println("Card: " + card.getDisplayNumber());
// ✓ Verify CVV
System.out.println("CVV valid: " + card.verifyCVV("123"));
// ✓ Process payment
card.processPayment("1000", "123");
// ❌ ไม่ได้:
// String number = card.getCardNumber(); // ERROR! No method
// String cvv = card.getCVV(); // ERROR! No method
}
}
Security Best Practices
1. Principle of Least Privilege (PoLP)
textให้ access ขั้นต่ำที่จำเป็นเท่านั้น
❌ ไม่ดี:
User ทั้งหมด → Full access
✓ ดี:
- Guest → Read only
- Employee → Read + limited write
- Manager → Read + write + approve
- Admin → Full access
2. Defense in Depth
textใช้หลายชั้น protection
┌────────────┐
│ Layer 1: Access Control (RBAC)
├────────────┤
│ Layer 2: Input Validation
├────────────┤
│ Layer 3: Encryption
├────────────┤
│ Layer 4: Audit Logging
├────────────┤
│ Layer 5: Monitoring & Alerts
└────────────┘
ตัวอย่างที่ 5: Banking System ด้วย Multiple Security Layers
javapublic class BankingSystem {
// Layer 1: Access Control
private enum Role { CUSTOMER, TELLER, MANAGER, AUDITOR }
// Layer 2: Input Validation
private static final double MAX_TRANSACTION = 100000;
private static final int MAX_LOGIN_ATTEMPTS = 3;
}
public class BankAccount {
private String accountNumber;
private String accountHolder;
private double balance;
private List<String> auditLog; // Layer 4: Audit
public void withdraw(double amount, User user) {
try {
// Layer 1: Access Control
if (!user.hasRole("CUSTOMER")) {
throw new SecurityException("Unauthorized");
}
// Layer 2: Input Validation
if (amount <= 0) {
throw new IllegalArgumentException("Amount must be positive");
}
if (amount > 100000) {
throw new IllegalArgumentException("Exceeds daily limit");
}
if (amount > this.balance) {
throw new IllegalArgumentException("Insufficient balance");
}
// Layer 3: Encryption (in real implementation)
String encryptedAmount = encryptAmount(amount);
// Execute transaction
this.balance -= amount;
// Layer 4: Audit Logging
logTransaction("WITHDRAW", amount, user.getUserID());
System.out.printf("✓ Withdrew %.2f from account %s\n",
amount, accountNumber);
} catch (Exception e) {
// Layer 4: Log errors
logTransaction("WITHDRAW_FAILED", amount, user.getUserID());
System.out.println("Error: " + e.getMessage());
// Layer 5: Alert (if needed)
if (isAnomalous(amount)) {
sendSecurityAlert("Suspicious activity detected");
}
}
}
private void logTransaction(String type, double amount, String userID) {
auditLog.add(String.format("[%s] %s: %.2f by %s",
System.currentTimeMillis(), type, amount, userID));
}
private boolean isAnomalous(double amount) {
return amount > 50000; // Simplified
}
private void sendSecurityAlert(String message) {
System.out.println("⚠️ SECURITY ALERT: " + message);
}
private String encryptAmount(double amount) {
return "ENCRYPTED_" + amount;
}
}
Data Privacy Checklist
ตรวจสอบก่อนเขียน Code
text┌─────────────────────────────────────────┐
│ Data Privacy Checklist │
├─────────────────────────────────────────┤
│ │
│ ✓ Identify sensitive data │
│ □ Passwords, keys, tokens │
│ □ Personal info (name, ID, email) │
│ □ Financial info (balance, card) │
│ □ Health/medical records │
│ │
│ ✓ Classify data (Public/Internal/Conf)│
│ │
│ ✓ Implement access control (RBAC) │
│ │
│ ✓ Encrypt sensitive data │
│ │
│ ✓ Hash passwords + use salt │
│ │
│ ✓ Validate all inputs │
│ │
│ ✓ Log access/changes (audit trail) │
│ │
│ ✓ Monitor anomalies │
│ │
│ ✓ Test security (penetration testing) │
│ │
└─────────────────────────────────────────┘
สรุป: Modeling Data Privacy
text┌────────────────────────────────────────┐
│ Data Privacy & Security Principles │
├────────────────────────────────────────┤
│ │
│ 1. CONFIDENTIALITY │
│ └─ ซ่อนข้อมูลสำคัญ │
│ │
│ 2. INTEGRITY │
│ └─ ข้อมูลต้องถูกต้องสมบูรณ์ │
│ │
│ 3. AVAILABILITY │
│ └─ สามารถเข้าถึงเมื่อต้องการ │
│ │
│ 4. DATA CLASSIFICATION │
│ └─ Public/Internal/Confidential │
│ │
│ 5. RBAC (Role-Based Access Control) │
│ └─ เข้าถึงตามบทบาท │
│ │
│ 6. DEFENSE IN DEPTH │
│ └─ หลายชั้น protection │
│ │
│ 7. AUDIT LOGGING │
│ └─ บันทึก access/changes │
│ │
└────────────────────────────────────────┘
ตัวอย่างสุดท้าย: Medical Records System
javapublic class PatientRecord {
// === PUBLIC DATA ===
private String patientName;
private String patientID;
// === CONFIDENTIAL DATA ===
private String medicalHistory;
private String currentMedications;
private String allergies;
// === RESTRICTED DATA ===
private String ssn;
private String insuranceInfo;
// === AUDIT ===
private List<AccessLog> accessLog;
public PatientRecord(String name, String id) {
this.patientName = name;
this.patientID = id;
this.accessLog = new ArrayList<>();
}
// === ACCESS CONTROL ===
public String getPatientName() {
return this.patientName; // PUBLIC
}
public String getMedicalHistory(User user) {
if (!user.hasRole("DOCTOR")) {
throw new SecurityException("Only doctors can access");
}
logAccess(user, "VIEW_MEDICAL_HISTORY");
return this.medicalHistory; // CONFIDENTIAL
}
public String getInsuranceInfo(User user) {
if (!user.hasRole("BILLING")) {
throw new SecurityException("Only billing staff");
}
logAccess(user, "VIEW_INSURANCE");
return this.insuranceInfo; // RESTRICTED
}
public void updateMedications(User user, String newMedications) {
if (!user.hasRole("DOCTOR")) {
throw new SecurityException("Only doctors can update");
}
this.currentMedications = newMedications;
logAccess(user, "UPDATE_MEDICATIONS");
}
private void logAccess(User user, String action) {
accessLog.add(new AccessLog(
System.currentTimeMillis(),
user.getUserID(),
user.getRole(),
action
));
}
public void displayAccessLog(User user) {
if (!user.hasRole("AUDITOR")) {
throw new SecurityException("Only auditors");
}
System.out.println("=== Access Log ===");
for (AccessLog log : accessLog) {
System.out.println(log);
}
}
static class AccessLog {
private long timestamp;
private String userID;
private String role;
private String action;
AccessLog(long timestamp, String userID, String role, String action) {
this.timestamp = timestamp;
this.userID = userID;
this.role = role;
this.action = action;
}
@Override
public String toString() {
return String.format("[%d] User:%s Role:%s Action:%s",
timestamp, userID, role, action);
}
}
}
// ใช้งาน
public class Main {
public static void main(String[] args) {
PatientRecord record = new PatientRecord("John Doe", "P001");
User doctor = new User("D001", "DOCTOR");
User billing = new User("B001", "BILLING");
User auditor = new User("A001", "AUDITOR");
System.out.println("=== Public Access ===");
System.out.println("Patient: " + record.getPatientName());
System.out.println("\n=== Doctor Access ===");
try {
String history = record.getMedicalHistory(doctor);
System.out.println("✓ Medical history accessed");
} catch (SecurityException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Billing Access ===");
try {
String insurance = record.getInsuranceInfo(billing);
System.out.println("✓ Insurance accessed");
} catch (SecurityException e) {
System.out.println("Error: " + e.getMessage());
}
System.out.println("\n=== Unauthorized Access ===");
try {
String history = record.getMedicalHistory(billing); // ❌ Billing is not doctor
} catch (SecurityException e) {
System.out.println("❌ Error: " + e.getMessage());
}
System.out.println("\n=== Audit Log ===");
record.displayAccessLog(auditor);
}
}
Output:
text=== Public Access ===
Patient: John Doe
=== Doctor Access ===
✓ Medical history accessed
=== Billing Access ===
✓ Insurance accessed
=== Unauthorized Access ===
❌ Error: Only doctors can access
=== Audit Log ===
[1730310000000] User:D001 Role:DOCTOR Action:VIEW_MEDICAL_HISTORY
[1730310001000] User:B001 Role:BILLING Action:VIEW_INSURANCE
[1730310002000] User:B001 Role:BILLING Action:VIEW_MEDICAL_HISTORY (attempt)
