예제 #1
0
def auth_account(account):
    token_obj = AuthenticationToken()
    try:
        token_obj.authenticate(account["username"], account["password"])
        return token_obj
    except Exception:
        return False
예제 #2
0
    def test_authenticate_wrong_credentials(self):
        a = AuthenticationToken()

        # We assume these aren't actual, valid credentials.
        with self.assertRaises(YggdrasilError) as e:
            a.authenticate("Billy", "The Goat")

            err = "Invalid Credentials. Invalid username or password."
            self.assertEqual(e.error, err)
예제 #3
0
    def test_authenticate_wrong_credentials(self):
        a = AuthenticationToken()

        # We assume these aren't actual, valid credentials.
        with self.assertRaises(YggdrasilError) as e:
            a.authenticate("Billy", "The Goat")

            err = "Invalid Credentials. Invalid username or password."
            self.assertEqual(e.error, err)
예제 #4
0
    def test_authenticate_wrong_credentials(self):
        a = AuthenticationToken()

        # We assume these aren't actual, valid credentials.
        with self.assertRaises(YggdrasilError) as cm:
            a.authenticate("Billy", "The Goat")

        err = "[403] ForbiddenOperationException: " \
              "'Invalid credentials. Invalid username or password.'"
        self.maxDiff = 5000
        self.assertEqual(str(cm.exception), err)
예제 #5
0
    def test_init_positional(self):
        a = AuthenticationToken(FAKE_DATA["username"],
                                FAKE_DATA["access_token"],
                                FAKE_DATA["client_token"])

        self.assertEqual(a.username, FAKE_DATA["username"])
        self.assertEqual(a.access_token, FAKE_DATA["access_token"])
        self.assertEqual(a.client_token, FAKE_DATA["client_token"])
예제 #6
0
    def test_authenticate_no_password(self):
        a = AuthenticationToken()

        with self.assertRaises(TypeError):
            a.authenticate("username")
예제 #7
0
 def test_init_client_token(self):
     a = AuthenticationToken(client_token=FAKE_DATA["client_token"])
     self.assertEqual(a.client_token, FAKE_DATA["client_token"])
예제 #8
0
 def test_init_access_token(self):
     a = AuthenticationToken(access_token=FAKE_DATA["access_token"])
     self.assertEqual(a.access_token, FAKE_DATA["access_token"])
예제 #9
0
 def test_init_username(self):
     a = AuthenticationToken(username=FAKE_DATA["username"])
     self.assertEqual(a.username, FAKE_DATA["username"])
예제 #10
0
 def test_init_no_values(self):
     a = AuthenticationToken()
     self.assertIs(a.username, None)
     self.assertIs(a.access_token, None)
     self.assertIs(a.client_token, None)
예제 #11
0
    def test_authenticate_no_password(self):
        a = AuthenticationToken()

        with self.assertRaises(TypeError):
            a.authenticate("username")
예제 #12
0
    def test_login_connect_and_logout(self):
        a = AuthenticationToken()

        successful_res = mock.NonCallableMock(requests.Response)
        successful_res.status_code = 200
        successful_res.json = mock.MagicMock(
            return_value={
                "accessToken": "token",
                "clientToken": "token",
                "selectedProfile": {
                    "id": "1",
                    "name": "asdf"
                }
            })
        successful_res.text = json.dumps(successful_res.json())

        error_res = mock.NonCallableMock(requests.Response)
        error_res.status_code = 400
        error_res.json = mock.MagicMock(return_value={
            "error": "invalid request",
            "errorMessage": "invalid request"
        })
        error_res.text = json.dumps(error_res.json())

        def mocked_make_request(server, endpoint, data):
            if endpoint == "authenticate":
                return successful_res
            if endpoint == "refresh" and data["accessToken"] == "token":
                return successful_res
            if (endpoint == "validate" and data["accessToken"] == "token") \
                    or endpoint == "join":
                r = requests.Response()
                r.status_code = 204
                r.raise_for_status = mock.MagicMock(return_value=None)
                return r
            if endpoint == "signout":
                return successful_res
            if endpoint == "invalidate":
                return successful_res

            return error_res

        # Test a successful sequence of events
        with mock.patch("minecraft.authentication._make_request",
                        side_effect=mocked_make_request) as _make_request_mock:

            self.assertFalse(a.authenticated)
            self.assertTrue(a.authenticate("username", "password"))

            self.assertTrue(a.authenticated)

            self.assertTrue(a.refresh())
            self.assertTrue(a.validate())

            self.assertTrue(a.authenticated)

            self.assertTrue(a.join(123))
            self.assertTrue(a.sign_out("username", "password"))

            self.assertTrue(a.invalidate())

            self.assertEqual(_make_request_mock.call_count, 6)

        a = AuthenticationToken(username="******",
                                access_token="token",
                                client_token="token")

        # Failures
        with mock.patch("minecraft.authentication._make_request",
                        return_value=error_res) as _make_request_mock:
            self.assertFalse(a.authenticated)

            a.client_token = "token"
            a.access_token = None
            self.assertRaises(ValueError, a.refresh)

            a.client_token = None
            a.access_token = "token"
            self.assertRaises(ValueError, a.refresh)

            a.access_token = None
            self.assertRaises(ValueError, a.validate)

            self.assertRaises(YggdrasilError, a.join, 123)
            self.assertRaises(YggdrasilError, a.invalidate)
예제 #13
0
def main() -> int:

    # Handle program arguments
    ap = argparse.ArgumentParser(
        prog="mchat",
        description="A console chat client for most Minecraft server versions")
    ap.add_argument("server_address", help="IP address of a Minecraft server")
    ap.add_argument("-p",
                    "--port",
                    help="Minecraft server port (default: %(default)s)",
                    type=int,
                    default=25565)
    ap.add_argument("-u", "--username", help="Minecraft username or email")
    ap.add_argument(
        "-v",
        "--version",
        help="Client -> Server protocol version to use (default: %(default)s)",
        default="1.16.4")
    args = ap.parse_args()

    # Verify server version to keep the terminal looking clean
    if args.version not in SUPPORTED_MINECRAFT_VERSIONS.keys():
        console.print(
            f"[bold yellow]{args.version} is not a valid Minecraft version. Versions from {list(SUPPORTED_MINECRAFT_VERSIONS.keys())[0]} to {list(SUPPORTED_MINECRAFT_VERSIONS.keys())[-1]} are allowed."
        )
        return 1

    # Do authentication
    if not args.username:
        username = Prompt.ask("Username or email")
    else:
        username = args.username

    password = getpass.getpass("Password: "******"[bright_black]Loaded authentication information")

    # Determine the actual protocol version number
    protocol_version_num = SUPPORTED_MINECRAFT_VERSIONS[args.version]
    console.print(
        f"[bright_black]Selecting protocol version {protocol_version_num}")

    # Authenticate with Mojang
    auth_token = AuthenticationToken()
    console.print(f"[bright_black]Contacting Yggdrasil...")

    try:
        auth_token.authenticate(username, password)
    except YggdrasilError as e:
        console.print(f"[bold red]Failed to authenticate Minecraft session")
        return 1

    # Open a connection
    server_connection = Connection(args.server_address,
                                   args.port,
                                   auth_token,
                                   allowed_versions=[protocol_version_num])

    try:
        server_connection.connect()
    except:
        console.print(f"[bold red]Could not connect to server")
        return 1

    # Set up an incoming chat handler
    server_connection.register_packet_listener(incomingChatHandler,
                                               ChatMessagePacket)
    console.print(f"[bright_black]Listen to incoming chat packets")

    # Set up input loop
    console.print(
        "All further inputs will be sent to server chat. Press CTRL+C to stop")
    try:
        while True:

            # Get a line from the user
            chat_message = console.input()

            # Send the chat message
            packet = serverbound.play.ChatPacket()
            packet.message = chat_message
            server_connection.write_packet(packet)

    except KeyboardInterrupt as e:
        print("\rGoodbye")

    return 0
예제 #14
0
    def test_login_connect_and_logout(self):
        a = AuthenticationToken()

        successful_res = mock.NonCallableMock(requests.Response)
        successful_res.status_code = 200
        successful_res.json = mock.MagicMock(
            return_value={"accessToken": "token",
                          "clientToken": "token",
                          "selectedProfile": {
                              "id": "1",
                              "name": "asdf"
                          }}
        )
        successful_res.text = json.dumps(successful_res.json())

        error_res = mock.NonCallableMock(requests.Response)
        error_res.status_code = 400
        error_res.json = mock.MagicMock(
            return_value={
                "error": "invalid request",
                "errorMessage": "invalid request"
            }
        )
        error_res.text = json.dumps(error_res.json())

        def mocked_make_request(server, endpoint, data):
            if endpoint == "authenticate":
                if "accessToken" in data:
                    response = successful_res.copy()
                    response.json["accessToken"] = data["accessToken"]
                    return response
                return successful_res
            if endpoint == "refresh" and data["accessToken"] == "token":
                return successful_res
            if (endpoint == "validate" and data["accessToken"] == "token") \
                    or endpoint == "join":
                r = requests.Response()
                r.status_code = 204
                r.raise_for_status = mock.MagicMock(return_value=None)
                return r
            if endpoint == "signout":
                return successful_res
            if endpoint == "invalidate":
                return successful_res

            return error_res

        # Test a successful sequence of events
        with mock.patch("minecraft.authentication._make_request",
                        side_effect=mocked_make_request) as _make_request_mock:

            self.assertFalse(a.authenticated)
            self.assertTrue(a.authenticate("username", "password"))

            self.assertEqual(_make_request_mock.call_count, 1)
            self.assertIn("clientToken", _make_request_mock.call_args[0][2])

            self.assertTrue(a.authenticated)

            self.assertTrue(a.refresh())
            self.assertTrue(a.validate())

            self.assertTrue(a.authenticated)

            self.assertTrue(a.join(123))
            self.assertTrue(a.sign_out("username", "password"))

            self.assertTrue(a.invalidate())

            self.assertEqual(_make_request_mock.call_count, 6)

        # Test that we send a provided clientToken if the authenticationToken
        # is initialized with one
        with mock.patch("minecraft.authentication._make_request",
                        side_effect=mocked_make_request) as _make_request_mock:
            a = AuthenticationToken(client_token="existing_token")

            self.assertTrue(a.authenticate("username", "password",
                                           invalidate_previous=False))

            self.assertEqual(_make_request_mock.call_count, 1)
            self.assertEqual(
                "existing_token",
                _make_request_mock.call_args[0][2]["clientToken"]
            )

        # Test that we invalidate previous tokens properly
        with mock.patch("minecraft.authentication._make_request",
                        side_effect=mocked_make_request) as _make_request_mock:
            a = AuthenticationToken()

            self.assertFalse(a.authenticated)
            self.assertTrue(a.authenticate("username", "password",
                                           invalidate_previous=True))

            self.assertTrue(a.authenticated)
            self.assertEqual(a.access_token, "token")
            self.assertEqual(_make_request_mock.call_count, 1)
            self.assertNotIn("clientToken", _make_request_mock.call_args[0][2])

        a = AuthenticationToken(username="******",
                                access_token="token",
                                client_token="token")

        # Failures
        with mock.patch("minecraft.authentication._make_request",
                        return_value=error_res) as _make_request_mock:
            self.assertFalse(a.authenticated)

            a.client_token = "token"
            a.access_token = None
            self.assertRaises(ValueError, a.refresh)

            a.client_token = None
            a.access_token = "token"
            self.assertRaises(ValueError, a.refresh)

            a.access_token = None
            self.assertRaises(ValueError, a.validate)

            self.assertRaises(YggdrasilError, a.join, 123)
            self.assertRaises(YggdrasilError, a.invalidate)
예제 #15
0
    def test_authenticate_good_credentials(self):
        a = AuthenticationToken()

        resp = a.authenticate(username, password)
        self.assertTrue(resp)
예제 #16
0
    def test_authenticate_good_credentials(self):
        a = AuthenticationToken()

        resp = a.authenticate(username, password)
        self.assertTrue(resp)
예제 #17
0
    def test_login_connect_and_logout(self):
        a = AuthenticationToken()

        successful_req = requests.Request()
        successful_req.status_code = 200
        successful_req.json = mock.MagicMock(
            return_value={"accessToken": "token",
                          "clientToken": "token",
                          "selectedProfile": {
                              "id": "1",
                              "name": "asdf"
                          }}
        )

        error_req = requests.Request()
        error_req.status_code = 400
        error_req.json = mock.MagicMock(
            return_value={
                "error": "invalid request",
                "errorMessage": "invalid request"
            }
        )

        def mocked_make_request(server, endpoint, data):
            if endpoint == "authenticate":
                return successful_req
            if endpoint == "refresh" and data["accessToken"] == "token":
                return successful_req
            if (endpoint == "validate" and data["accessToken"] == "token") \
                    or endpoint == "join":
                r = requests.Request()
                r.status_code = 204
                r.raise_for_status = mock.MagicMock(return_value=None)
                return r
            if endpoint == "signout":
                return successful_req
            if endpoint == "invalidate":
                return successful_req

            return error_req

        # Test a successful sequence of events
        with mock.patch("minecraft.authentication._make_request",
                        side_effect=mocked_make_request) as _make_request_mock:

            self.assertFalse(a.authenticated)
            self.assertTrue(a.authenticate("username", "password"))

            self.assertTrue(a.authenticated)

            self.assertTrue(a.refresh())
            self.assertTrue(a.validate())

            self.assertTrue(a.authenticated)

            self.assertTrue(a.join(123))
            self.assertTrue(a.sign_out("username", "password"))

            self.assertTrue(a.invalidate())

            self.assertEqual(_make_request_mock.call_count, 6)

        a = AuthenticationToken(username="******",
                                access_token="token",
                                client_token="token")

        # Failures
        with mock.patch("minecraft.authentication._make_request",
                        return_value=error_req) as _make_request_mock:
            self.assertFalse(a.authenticated)

            a.client_token = "token"
            a.access_token = None
            self.assertRaises(ValueError, a.refresh)

            a.client_token = None
            a.access_token = "token"
            self.assertRaises(ValueError, a.refresh)

            a.access_token = None
            self.assertRaises(ValueError, a.validate)

            self.assertRaises(YggdrasilError, a.join, 123)
            self.assertRaises(YggdrasilError, a.invalidate)