Menu
CoddyTech

Ocultación de información

Parte de la sección Programación orientada a objetos del Journey de Python de Coddy. Lección 30 de 64.

La ocultación de información restringe el acceso directo a los componentes de un objeto y exige que todas las interacciones se realicen a través de interfaces bien definidas. Esto protege los datos internos del acceso no autorizado.

Aquí tienes un ejemplo de una clase con distintos niveles de ocultación de información:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner                    # Público - se puede acceder directamente
        self._balance = initial_balance       # Protegido - para uso interno
        self.__account_number = "ACC123456"   # Privado - oculto desde el exterior

Añade métodos que proporcionen acceso controlado a los datos ocultos:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner
        self._balance = initial_balance
        self.__account_number = "ACC123456"
        
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
            return True
        return False
    
    def withdraw(self, amount):
        if amount > 0 and amount <= self._balance:
            self._balance -= amount
            return True
        return False
    
    def get_balance(self):
        return self._balance
    
    def get_account_info(self):
        # Forma segura de mostrar datos privados parciales
        return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"

Usa la clase a través de su interfaz pública:

account = BankAccount("Alice", 1000)

Accede directamente a los datos públicos:

print(account.owner)  # Alice - acceso público permitido

Usa métodos controlados para los datos protegidos:

print(account.get_balance())  # 1000 - acceso controlado
account.deposit(500)
print(account.get_balance())  # 1500 - saldo modificado de forma segura

Intenta acceder a los datos ocultos:

print(account.get_account_info())  # Propietario: Alice, Cuenta: ***3456
# print(account.__account_number)  # AttributeError - oculto

El atributo privado tiene su nombre manipulado, pero sigue siendo técnicamente accesible:

# Esto funciona, pero vulnera el principio de ocultación de información:
print(account._BankAccount__account_number)  # ACC123456

Salida:

Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456

Punto clave: La ocultación de información protege los datos internos al hacerlos privados o protegidos y después proporcionar acceso controlado mediante métodos públicos. Esto evita la manipulación directa de datos confidenciales y garantiza su integridad mediante la validación en los métodos de acceso.

challenge icon

Desafío

Intermedio

En este desafío, implementarás un sistema de mensajería seguro con pruebas exhaustivas para validar tu solución.

Debes editar securemessenger.py para implementar la clase SecureMessenger siguiendo los principios de ocultación de información. El archivo contiene comentarios detallados de TODO para guiar tu implementación.

Los requisitos principales incluyen:

  • Encapsulación adecuada de las credenciales y los mensajes
  • Autenticación antes de permitir operaciones con mensajes
  • Supervisión de seguridad mediante el seguimiento de los intentos de inicio de sesión
  • Mensajes de retorno precisos, según se especifica en los TODO

Pruébalo tú mismo

from securemessenger import SecureMessenger

# Gestor de casos de prueba
test_case = input()
if test_case == "default_test":
    # Caso de prueba estándar del problema original
    messenger = SecureMessenger("user1")
    
    # Intenta añadir mensajes antes de iniciar sesión
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # Intenta iniciar sesión con una contraseña incorrecta
    print(messenger.login("wrong_pass"))
    
    # Inicia sesión con la contraseña correcta
    print(messenger.login("secure123"))
    
    # Añade mensajes después de iniciar sesión correctamente
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # Recupera los mensajes
    print(messenger.get_messages())
    
    # Comprueba los intentos de inicio de sesión
    print(messenger.get_login_attempts())
elif test_case == "custom_password":
    # Prueba con una contraseña personalizada
    messenger = SecureMessenger("admin", "admin123")
    print(messenger.login("wrong_password"))
    print(messenger.login("admin123"))
    print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
    # Prueba varios intentos de inicio de sesión
    messenger = SecureMessenger("user2")
    print(messenger.login("attempt1"))
    print(messenger.login("attempt2"))
    print(messenger.login("attempt3"))
    print(messenger.login("secure123"))
    print(messenger.get_login_attempts())
elif test_case == "message_management":
    # Gestión de Test message
    messenger = SecureMessenger("user3")
    print(messenger.login("secure123"))
    
    # Añade varios mensajes
    messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
    for msg in messages:
        print(messenger.add_message(msg))
    
    # Verifica todos los mensajes
    print(messenger.get_messages())
elif test_case == "empty_messages":
    # Prueba el caso de mensajes vacíos
    messenger = SecureMessenger("user4")
    print(messenger.login("secure123"))
    print(messenger.get_messages())
elif test_case == "access_without_login":
    # Prueba el acceso sin iniciar sesión
    messenger = SecureMessenger("user5")
    print(messenger.add_message("Unauthorized message"))
    print(messenger.get_messages())
elif test_case == "attribute_privacy":
    # Prueba la privacidad de los atributos
    messenger = SecureMessenger("user6")
    
    # Atributo público
    print(f"Public username: {messenger.username}")
    
    # Atributos privados: estos deberían generar AttributeError
    try:
        print(messenger.__password)
    except AttributeError as e:
        print("Password is private: AttributeError")
    
    try:
        print(messenger.__messages)
    except AttributeError as e:
        print("Messages are private: AttributeError")
    
    try:
        print(messenger.__login_attempts)
    except AttributeError as e:
        print("Login attempts are private: AttributeError")
    
    try:
        print(messenger.__is_logged_in)
    except AttributeError as e:
        print("Login status is private: AttributeError")
elif test_case == "login_logout_sequence":
    # Esta prueba requiere ampliar la clase con un método logout
    # Para realizar la prueba, crearemos una subclase con funcionalidad de cierre de sesión
    class ExtendedMessenger(SecureMessenger):
        def logout(self):
            self._SecureMessenger__is_logged_in = False
            return "Logged out successfully"
    
    messenger = ExtendedMessenger("user7")
    print(messenger.login("secure123"))
    print(messenger.add_message("Test message"))
    print(messenger.get_messages())
    print(messenger.logout())
    print(messenger.get_messages())
elif test_case == "stress_test":
    # Prueba de estrés con muchos mensajes
    messenger = SecureMessenger("user8")
    print(messenger.login("secure123"))
    
    # Añade 100 mensajes
    for i in range(1, 101):
        messenger.add_message(f"Message {i}")
    
    # Verifica la cantidad de mensajes
    messages = messenger.get_messages()
    newline_char = '\n'  # Guarda el carácter de nueva línea en una variable
    message_count = len(messages.split(newline_char))
    print(f"Added 100 messages. Retrieved {message_count} messages.")
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Compilador de Python online