Exemplo n.º 1
0
def json_and_response_code(uuid):
    if len(uuid) != 32:
        return "", 204

    try:
        uuid_object = UUID(uuid)
    except ValueError:
        return "", 204

    profile = Profile.get(uuid=uuid_object)

    if profile is None:
        return "", 204

    history = []

    for event in profile.profile_name_events.order_by(desc(ProfileNameEvent.active_from)):
        event: ProfileNameEvent
        if event.is_initial_name:
            history.append({
                "name": event.name
            })
        else:
            history.append({
                "name": event.name,
                "changedToAt": int(event.active_from.timestamp())
            })

    return jsonify(history), 200
Exemplo n.º 2
0
def call(program, argv):
    parser = argparse.ArgumentParser(prog=program)

    parser.add_argument("dbid", help="DBID of profile", type=int)
    parser.add_argument("--unix",
                        help="show timestamps as integer",
                        action="store_true")

    args = parser.parse_args(argv)

    profile: Profile = Profile.get(id=args.dbid)
    if profile is None:
        print("No profile matches that DBID!")
        exit(1)

    print(f"History of {profile}")
    print(
        f"Current name styles: {profile.name}, {profile.name_upper}, {profile.name_lower}"
    )

    for event in profile.profile_name_events.order_by(
            desc(ProfileNameEvent.active_from)):
        if args.unix:
            print(event.repr_timestamp())
        else:
            print(event)
Exemplo n.º 3
0
def call(program, argv):
    parser = argparse.ArgumentParser(prog=program)

    parser.add_argument("dbid", help="DBID of profile", type=int)
    parser.add_argument("timestamp", help="timestamp", type=int)

    args = parser.parse_args(argv)

    profile: Profile = Profile.get(id=args.dbid)
    if profile is None:
        print("No profile matches that DBID!")
        exit(1)

    try:
        event = profile.owned_name_at(datetime.utcfromtimestamp(
            args.timestamp))
    except OSError:
        print("Invalid timestamp.")
        exit(1)

    if event is None:
        print("This profile didn't have a name at that time.")
        exit(1)

    print(event)
Exemplo n.º 4
0
def json_and_response_code(request):
    if "clientToken" not in request.json or request.json["clientToken"] is None:
        return NULL_CLIENT_TOKEN.dual

    if "accessToken" not in request.json or request.json["accessToken"] is None:
        return NULL_ACCESS_TOKEN.dual

    access_token = AccessToken.from_token(request.json["accessToken"])
    try:
        if access_token is None or access_token.client_token.uuid != UUID(
                request.json["clientToken"]):
            return INVALID_TOKEN.dual
    except ValueError:
        return INVALID_UUID.dual

    if "selectedProfile" in request.json:
        try:
            _selected_uuid = UUID(request.json["selectedProfile"]["id"])
        except ValueError:
            return INVALID_UUID.dual
        new_profile = Profile.get(
            lambda x: x.uuid == _selected_uuid and x.name == request.json[
                "selectedProfile"][
                    "name"] and x.account == access_token.client_token.account)
        if new_profile is None:
            return PROFILE_NOT_FOUND.dual
    else:
        new_profile = access_token.profile

    new_access_token = AccessToken(
        client_token=access_token.client_token,
        profile=new_profile,
    )

    access_token.delete()

    response_data = {
        "accessToken": jwt_encode(new_access_token.format(), key="").decode(),
        "clientToken": request.json["clientToken"],
    }

    if new_access_token.profile:
        response_data["selectedProfile"] = {
            "id": new_access_token.profile.uuid.hex,
            "name": new_access_token.profile.name
        }

    if "requestUser" in request.json and request.json["requestUser"]:
        response_data["user"] = {
            "id": new_access_token.client_token.account.uuid.hex,
            "username": new_access_token.client_token.account.username
        }

    return jsonify(response_data), 200
Exemplo n.º 5
0
def call(program, argv):
    parser = ArgumentParser(prog=program)

    parser.add_argument("dbid", help="DBID of profile", type=int)

    sources = parser.add_mutually_exclusive_group(required=True)
    sources.add_argument("-u", "--url", help="url of skin", dest="url")
    sources.add_argument("-f", help="file path of skin", dest="path")
    sources.add_argument("--delete",
                         help="reset profile skin",
                         action="store_true")

    parser.add_argument("--slim", help="slim model", action="store_true")

    args = parser.parse_args(argv)

    profile: Profile = Profile.get(id=args.dbid)
    if profile is None:
        print("No profile matches that DBID!")
        exit(1)

    if args.url is not None:
        fd = BytesIO(get(args.url).content)
    elif args.path is not None:
        fd = Path(args.path)
    elif not args.delete:
        print("You must specify a file!")
        exit(1)

    if args.delete:
        profile.reset_skin()
    else:
        try:
            image: Image = Image.open(fd)
        except (FileNotFoundError, UnidentifiedImageError, ValueError):
            print(INVALID_IMAGE.message)
            exit(1)

        try:
            profile.update_skin(image, "slim" if args.slim else "")
        except ValueError:
            print(INVALID_SKIN.message)
            exit(1)

    try:
        commit()
    except Exception as e:
        print(e)
        exit(1)

    if not args.delete:
        print(f"Texture name: {profile.profile_skin.name}")
Exemplo n.º 6
0
def json_and_response_code(request, uuid, textures_host):
    try:
        uuid_object = UUID(uuid)
    except ValueError:
        return "", 204

    profile = Profile.get(uuid=uuid_object)
    if profile is None:
        return "", 204

    unsigned = request.args.get("unsigned")
    if unsigned is not None and unsigned == "false":
        return jsonify(
            get_public_profile_details(profile, False, textures_host)), 200
    return jsonify(get_public_profile_details(profile, True,
                                              textures_host)), 200
Exemplo n.º 7
0
def json_and_response_code(request: Request, uuid):
    try:
        token = AccessToken.from_header(request.headers.get("Authorization"))
    except InvalidAuthHeaderException:
        return AUTH_HEADER_MISSING.dual
    if token is None:
        # May be inconsistent with official API
        return INVALID_TOKEN.dual

    try:
        uuid_object = UUID(uuid)
    except ValueError:
        # May be inconsistent with official API
        return INVALID_UUID.dual

    profile: Profile = Profile.get(uuid=uuid_object)
    if profile is None or profile.account != token.client_token.account:
        # May be inconsistent with official API
        return INVALID_TOKEN.dual

    if not profile.account.does_trust_ip(request.remote_addr):
        return UNTRUSTED_IP.dual

    if request.method == "POST":
        if "model" not in request.form or "url" not in request.form:
            # May be inconsistent with official API
            return MISSING_SKIN.dual

        response = get(request.form["url"])
        return set_skin(BytesIO(response.content), request.form["model"],
                        profile)

    elif request.method == "PUT":
        if "file" not in request.files or "model" not in request.form:
            # May be inconsistent with official API
            return NULL_MESSAGE.dual
        return set_skin(request.files["file"].stream, request.form["model"],
                        profile)

    elif request.method == "DELETE":
        profile.reset_skin()
        return "", 204

    return "", 204
Exemplo n.º 8
0
def call(program, argv):
    parser = argparse.ArgumentParser(prog=program)

    parser.add_argument("dbid", help="DBID of profile", type=int)

    uuids = parser.add_mutually_exclusive_group()
    uuids.add_argument("-u", "--uuid", help="change profile UUID", type=UUID)
    uuids.add_argument("-ru",
                       "--random-uuid",
                       help="refresh profile UUID",
                       action="store_true")

    parser.add_argument("-a", "--agent", help="change profile agent")
    parser.add_argument("--delete",
                        help="delete this profile",
                        action="store_true")

    args = parser.parse_args(argv)

    profile: Profile = Profile.get(id=args.dbid)
    if profile is None:
        print("No profile matches that DBID!")
        exit(1)

    if args.uuid is not None:
        profile.uuid = args.uuid
    if args.random_uuid:
        profile.uuid = uuid4()
    if args.agent is not None:
        profile.agent = args.agent
    if args.delete:
        profile.delete()

    try:
        commit()
    except Exception as e:
        print(e)
        exit(1)

    if not args.delete:
        print(str(profile))
Exemplo n.º 9
0
def call(program, argv):
    parser = argparse.ArgumentParser(prog=program)

    parser.add_argument("dbid", help="DBID of profile", type=int)
    parser.add_argument("name", help="new name of profile")

    parser.add_argument("--bypass-wait",
                        help="do not wait 30 days between name changes",
                        action="store_true")
    parser.add_argument("--bypass-lock",
                        help="do not wait 37 days for profile name to unlock",
                        action="store_true")

    args = parser.parse_args(argv)

    profile: Profile = Profile.get(id=args.dbid)
    if profile is None:
        print("No profile matches that DBID!")
        exit(1)

    if not (args.bypass_wait or profile.can_change_name()):
        print(
            f"Cannot change name until {profile.time_of_next_name_change()}. Wait {profile.time_to_name_change()}."
        )
        exit(1)

    if not (args.bypass_lock
            or profile.is_name_available_for_change(args.name)):
        print("Name not available.")
        exit(1)

    profile.change_name(args.name)

    try:
        commit()
    except Exception as e:
        print(e)
        exit(1)

    print(profile)
Exemplo n.º 10
0
def join_mcclient(request: Request):
    if "accessToken" not in request.json:
        # May be inconsistent with official API
        return NULL_ACCESS_TOKEN.dual

    if "selectedProfile" not in request.json or "serverId" not in request.json:
        # May be inconsistent with official API
        return NULL_MESSAGE.dual

    access_token = AccessToken.from_token(request.json["accessToken"])
    if access_token is None:
        # May be inconsistent with official API
        return INVALID_TOKEN.dual

    try:
        profile = Profile.get(
            lambda x: x.uuid == UUID(request.json["selectedProfile"]))
    except ValueError:
        # May be inconsistent with official API
        return INVALID_UUID.dual

    if access_token.profile != profile:
        # May be inconsistent with official API
        return INVALID_TOKEN.dual

    session = MCServerSession.get(
        lambda x: x.profile == profile and x.client_side_ip == request.
        remote_addr and x.server_hash == request.json["serverId"])

    if session is None:
        MCServerSession.select(lambda x: x.profile == profile).delete()
        MCServerSession(
            profile=profile,
            client_side_ip=request.remote_addr,
            server_hash=request.json["serverId"],
        )

    return "", 204