Exemple #1
0
 def __init__(self, event, online_mode, auth_timeout):
     self.online_mode = online_mode
     self.auth_timeout = auth_timeout
     self.__event = event
     self.ygg = YggdrasilCore()
     self._shared_secret = None
     self._username = None
Exemple #2
0
def test_request_raises_error(urlopen, request):
    exception_data = MagicMock()
    exception_data.read.return_value.decode.return_value = '{"error": 1}'
    urlopen.side_effect = HTTPError('', '', '', '', exception_data)

    ygg = YggdrasilCore()
    assert not urlopen.called
    assert not request.called
    res = ygg._ygg_req('/test', {'a': 'b'})

    # Read the response
    assert exception_data.read.called
    assert exception_data.read.return_value.decode.called

    assert res == {'error': 1}
Exemple #3
0
 def __init__(self, event, online_mode, auth_timeout):
     self.online_mode = online_mode
     self.auth_timeout = auth_timeout
     self.__event = event
     self.ygg = YggdrasilCore()
     self._shared_secret = None
     self._username = None
Exemple #4
0
def test_validate_error():
    ygg = YggdrasilCore()
    ygg._ygg_req = ygg_req = mock.MagicMock()
    ygg_req.return_value = {'whatever': 'dict'}

    ygg.access_token = 'accesstoken'
    res = ygg.validate()

    ygg_req.assert_called_once_with('/validate', {
        'accessToken': 'accesstoken',
    })

    assert '' == ygg.username
    assert '' == ygg.password
    assert '' == ygg.client_token
    assert 'accesstoken' == ygg.access_token
    assert not res
Exemple #5
0
def test_signout():
    ygg = YggdrasilCore()
    ygg._ygg_req = ygg_req = mock.MagicMock()
    ygg_req.return_value = {'whatever': 'dict'}

    ygg.username = '******'
    ygg.password = '******'
    res = ygg.signout()

    ygg_req.assert_called_once_with('/signout', {
        'username': '******',
        'password': '******',
    })

    assert ygg.username == 'user'
    assert ygg.password == 'pass'
    assert '' == ygg.client_token
    assert '' == ygg.access_token
    assert res
Exemple #6
0
def test_refresh_failure():
    ygg = YggdrasilCore()
    ygg._ygg_req = ygg_req = mock.MagicMock()
    ygg_req.return_value = {'error': 1}

    ygg.client_token = 'clienttoken'
    ygg.access_token = 'accesstoken'
    res = ygg.refresh()

    ygg_req.assert_called_once_with('/refresh', {
        'accessToken': 'accesstoken',
        'clientToken': 'clienttoken',
    })

    assert '' == ygg.username
    assert '' == ygg.password
    assert ygg.client_token == 'clienttoken'
    assert ygg.access_token == 'accesstoken'
    assert not res
Exemple #7
0
def test_authenticate_success():
    ygg = YggdrasilCore()
    ygg._ygg_req = ygg_req = mock.MagicMock()
    ygg_req.return_value = {'accessToken': 'myaccess',
                            'clientToken': 'mytoken',
                            'availableProfiles': ['a', 'b'],
                            'selectedProfile': 'a'}

    ygg.username = '******'
    ygg.password = '******'
    ygg.client_token = 'clienttoken'

    res = ygg.authenticate()

    ygg_req.assert_called_once_with('/authenticate', {
        'agent': {
            'name': 'Minecraft',
            'version': 1,
        },
        'username': '******',
        'password': '******',
        'clientToken': 'clienttoken',
    })

    assert ygg.username == 'user'
    assert ygg.password == 'pass'
    assert ygg.client_token == 'mytoken'
    assert ygg.access_token == 'myaccess'
    assert res
Exemple #8
0
def test_authenticate_failure():
    ygg = YggdrasilCore()
    ygg._ygg_req = ygg_req = mock.MagicMock()
    ygg_req.return_value = {'error': 1}

    ygg.username = '******'
    ygg.password = '******'
    ygg.client_token = 'clienttoken'
    res = ygg.authenticate()

    ygg_req.assert_called_once_with('/authenticate', {
        'agent': {
            'name': 'Minecraft',
            'version': 1,
        },
        'username': '******',
        'password': '******',
        'clientToken': 'clienttoken',
    })

    assert ygg.username == 'user'
    assert ygg.password == 'pass'
    assert ygg.client_token == 'clienttoken'
    assert '' == ygg.access_token
    assert not res
Exemple #9
0
def test_refresh_success():
    ygg = YggdrasilCore()
    ygg._ygg_req = ygg_req = mock.MagicMock()
    ygg_req.return_value = {'accessToken': 'myaccess',
                            'clientToken': 'mytoken',
                            'availableProfiles': ['a', 'b'],
                            'selectedProfile': 'a'}

    ygg.client_token = 'clienttoken'
    ygg.access_token = 'accesstoken'
    res = ygg.refresh()

    ygg_req.assert_called_once_with('/refresh', {
        'accessToken': 'accesstoken',
        'clientToken': 'clienttoken',
    })

    assert ygg.client_token == 'mytoken'
    assert ygg.access_token == 'myaccess'
    assert '' == ygg.username
    assert '' == ygg.password
    assert res
Exemple #10
0
def test_request_is_done(urlopen, request):
    decode = urlopen.return_value.read.return_value.decode
    decode.return_value = '{"test": 1}'
    ygg = YggdrasilCore()
    assert not urlopen.called
    assert not request.called
    res = ygg._ygg_req('/test', [{'a': 'b'}, 'c', 'd', 'e'])

    # First create the request
    request.assert_called_once_with(
        url='https://authserver.mojang.com/test',
        data=b'[{"a": "b"}, "c", "d", "e"]',
        headers={'Content-Type': 'application/json'}
    )

    # Then send it
    urlopen.assert_called_once_with(request.return_value)

    # Read the response
    assert urlopen.return_value.read.called
    assert decode.called

    assert res == {'test': 1}
Exemple #11
0
def test_yggdrasil_initialization():
    ygg = YggdrasilCore()
    assert '' == ygg.username
    assert '' == ygg.password
    assert '' == ygg.client_token
    assert '' == ygg.access_token
Exemple #12
0
class AuthCore(object):
    def __init__(self, event, online_mode, auth_timeout):
        self.online_mode = online_mode
        self.auth_timeout = auth_timeout
        self.__event = event
        self.ygg = YggdrasilCore()
        self._shared_secret = None
        self._username = None

    def get_username(self):
        return self._username

    def set_username(self, username):
        self.ygg.username = username

    username = property(get_username, set_username)

    def set_password(self, password):
        if password and not self.online_mode:
            logger.warning("PASSWORD PROVIDED WITH ONLINE_MODE == FALSE")
            logger.warning("YOU PROBABLY DIDN'T WANT TO DO THAT")
        self.ygg.password = password

    password = property(lambda x: bool(x.ygg.password), set_password)

    def set_client_token(self, client_token):
        if not self.online_mode:
            logger.warning("CLIENT TOKEN PROVIDED WITH ONLINE_MODE == FALSE")
            logger.warning("YOU PROBABLY DIDN'T WANT TO DO THAT")
        self.ygg.client_token = client_token

    client_token = property(lambda x: bool(x.ygg.client_token),
                            set_client_token)

    def set_auth_token(self, auth_token):
        if not self.online_mode:
            logger.warning("AUTH TOKEN PROVIDED WITH ONLINE_MODE == FALSE")
            logger.warning("YOU PROBABLY DIDN'T WANT TO DO THAT")
        self.ygg.auth_token = auth_token

    auth_token = property(lambda x: bool(x.ygg.auth_token), set_auth_token)

    def get_shared_secret(self):
        self._shared_secret = self._shared_secret or os.urandom(16)
        return self._shared_secret

    shared_secret = property(get_shared_secret)

    def start_session(self):
        if not self.online_mode:
            self._username = self.ygg.username
            return True
        if self.ygg.login():
            self._username = self.ygg.selected_profile['name']
            return True
        self.__event.emit('auth_session_error')
        return False

    def send_session_auth(self, pubkey_raw, server_id_raw):
        server_id = java_hex_digest(
            hashlib.sha1(
                server_id_raw.encode('ascii') + self.shared_secret +
                pubkey_raw))
        logger.info('Attempting to authenticate with Mojang session server')
        url = "https://sessionserver.mojang.com/session/minecraft/join"
        data = json.dumps({
            'accessToken': self.ygg.access_token,
            'selectedProfile': self.ygg.selected_profile,
            'serverId': server_id,
        }).encode('utf-8')
        headers = {'Content-Type': 'application/json'}
        req = request.Request(url, data, headers)
        try:
            rep = request.urlopen(
                req, timeout=self.auth_timeout).read().decode('ascii')
        except URLError:
            rep = "Couldn't connect to sessionserver.mojang.com"
        if rep:
            logger.warning('Mojang session auth response: %s', rep)
        logger.info('Session authentication successful')
Exemple #13
0
class AuthCore(object):
    def __init__(self, event, online_mode, auth_timeout):
        self.online_mode = online_mode
        self.auth_timeout = auth_timeout
        self.__event = event
        self.ygg = YggdrasilCore()
        self._shared_secret = None
        self._username = None

    def get_username(self):
        return self._username

    def set_username(self, username):
        self.ygg.username = username

    username = property(get_username, set_username)

    def set_password(self, password):
        if password and not self.online_mode:
            logger.warning("PASSWORD PROVIDED WITH ONLINE_MODE == FALSE")
            logger.warning("YOU PROBABLY DIDN'T WANT TO DO THAT")
        self.ygg.password = password

    password = property(lambda x: bool(x.ygg.password), set_password)

    def set_client_token(self, client_token):
        if not self.online_mode:
            logger.warning("CLIENT TOKEN PROVIDED WITH ONLINE_MODE == FALSE")
            logger.warning("YOU PROBABLY DIDN'T WANT TO DO THAT")
        self.ygg.client_token = client_token

    client_token = property(lambda x: bool(x.ygg.client_token), set_client_token)

    def set_auth_token(self, auth_token):
        if not self.online_mode:
            logger.warning("AUTH TOKEN PROVIDED WITH ONLINE_MODE == FALSE")
            logger.warning("YOU PROBABLY DIDN'T WANT TO DO THAT")
        self.ygg.auth_token = auth_token

    auth_token = property(lambda x: bool(x.ygg.auth_token), set_auth_token)

    def get_shared_secret(self):
        self._shared_secret = self._shared_secret or os.urandom(16)
        return self._shared_secret

    shared_secret = property(get_shared_secret)

    def start_session(self):
        if not self.online_mode:
            self._username = self.ygg.username
            return True
        if self.ygg.login():
            self._username = self.ygg.selected_profile["name"]
            return True
        self.__event.emit("auth_session_error")
        return False

    def send_session_auth(self, pubkey_raw, server_id_raw):
        server_id = java_hex_digest(hashlib.sha1(server_id_raw.encode("ascii") + self.shared_secret + pubkey_raw))
        logger.info("Attempting to authenticate with Mojang session server")
        url = "https://sessionserver.mojang.com/session/minecraft/join"
        data = json.dumps(
            {"accessToken": self.ygg.access_token, "selectedProfile": self.ygg.selected_profile, "serverId": server_id}
        ).encode("utf-8")
        headers = {"Content-Type": "application/json"}
        req = request.Request(url, data, headers)
        try:
            rep = request.urlopen(req, timeout=self.auth_timeout).read().decode("ascii")
        except URLError:
            rep = "Couldn't connect to sessionserver.mojang.com"
        if rep:
            logger.warning("Mojang session auth response: %s", rep)
        logger.info("Session authentication successful")