def __init__(self, http, airplay_player): """Initialize a new AirPlayInternal instance.""" self.player = airplay_player self.identifier = None self.srp = SRPAuthHandler() self.verifier = AuthenticationVerifier(http, self.srp) self.auther = DeviceAuthenticator(http, self.srp)
class AirPlayInternal(AirPlay): """Implementation of API for AirPlay support.""" def __init__(self, http, airplay_player): """Initialize a new AirPlayInternal instance.""" self.player = airplay_player self.identifier = None self.srp = SRPAuthHandler() self.verifier = AuthenticationVerifier(http, self.srp) self.auther = DeviceAuthenticator(http, self.srp) @asyncio.coroutine def generate_credentials(self): """Create new credentials for authentication. Credentials that have been authenticated shall be saved and loaded with load_credentials before playing anything. If credentials are lost, authentication must be performed again. """ identifier, seed = new_credentials() return '{0}:{1}'.format(identifier, seed.decode().upper()) @asyncio.coroutine def load_credentials(self, credentials): """Load existing credentials.""" split = credentials.split(':') self.identifier = split[0] self.srp.initialize(binascii.unhexlify(split[1])) _LOGGER.debug('Loaded AirPlay credentials: %s', credentials) def verify_authenticated(self): """Check if loaded credentials are verified.""" return self.verifier.verify_authed() def start_authentication(self): """Begin authentication proces (show PIN on screen).""" return self.auther.start_authentication() def finish_authentication(self, pin): """End authentication process with PIN code.""" return self.auther.finish_authentication(self.identifier, pin) @asyncio.coroutine def play_url(self, url, **kwargs): """Play media from an URL on the device. Note: This method will not yield until the media has finished playing. The Apple TV requires the request to stay open during the entire play duration. """ # If credentials have been loaded, do device verification first if self.identifier: yield from self.verify_authenticated() position = 0 if 'position' not in kwargs else int(kwargs['position']) return (yield from self.player.play_url(url, position))
def test_auth_failed(self): http = HttpSession( self.session, 'http://127.0.0.1:{0}/'.format(self.app.port)) handler = srp.SRPAuthHandler() handler.initialize(binascii.unhexlify(DEVICE_AUTH_KEY)) auther = DeviceAuthenticator(http, handler) yield from auther.start_authentication() self.assertTrue((yield from auther.finish_authentication( DEVICE_IDENTIFIER, DEVICE_PIN)))
def test_auth_successful(self): http = HttpSession( self.session, 'http://127.0.0.1:{0}/'.format(self.app.port)) handler = srp.SRPAuthHandler() handler.initialize(INVALID_AUTH_KEY) auther = DeviceAuthenticator(http, handler) yield from auther.start_authentication() with self.assertRaises(DeviceAuthenticationError): yield from auther.finish_authentication( DEVICE_IDENTIFIER, DEVICE_PIN)
async def test_auth_successful(self): http = HttpSession(self.session, "http://127.0.0.1:{0}/".format(self.server.port)) handler = srp.SRPAuthHandler() handler.initialize(binascii.unhexlify(DEVICE_AUTH_KEY)) authenticator = DeviceAuthenticator(http, handler) await authenticator.start_authentication() self.assertTrue( (await authenticator.finish_authentication(DEVICE_IDENTIFIER, DEVICE_PIN)))
async def test_auth_failed(self): http = HttpSession(self.session, "http://127.0.0.1:{0}/".format(self.server.port)) handler = srp.SRPAuthHandler() handler.initialize(INVALID_AUTH_KEY) authenticator = DeviceAuthenticator(http, handler) await authenticator.start_authentication() with self.assertRaises(AuthenticationError): await authenticator.finish_authentication(DEVICE_IDENTIFIER, DEVICE_PIN)
def __init__(self, config, session, _): """Initialize a new MrpPairingHandler.""" super().__init__(session, config.get_service(Protocol.AirPlay)) self.srp = SRPAuthHandler() self.http = net.HttpSession( session, f"http://{config.address}:{self.service.port}/") self.authenticator = DeviceAuthenticator(self.http, self.srp) self.auth_data = self._setup_credentials() self.srp.initialize(binascii.unhexlify(self.auth_data.seed)) self.pin_code = None self._has_paired = False