Beispiel #1
0
async def test_positive_register_w_email_and_name(test_cli):
    global username
    username = None
    while username is None:
        i = random.randint(1, 10000)
        username = f"amichay.oren+{i}@gmail.com"
        if User.username_exists(username):
            username = None

    data = {
        "username": username,
        "password": "******",
        "email": username,
        "name": "Amichay Oren",
    }
    resp = await test_cli.post("/users", data=json.dumps(data))

    assert resp.status == 201

    data = {"username": username, "password": "******"}
    resp = await test_cli.post("/auth", data=json.dumps(data))
    resp_json = await resp.json()
    print(resp_json)
    global access_token
    access_token = resp_json["access_token"]
    global refresh_token
    refresh_token = resp_json["refresh_token"]
    assert access_token is not None
    assert refresh_token is not None
    assert resp.status == 200
Beispiel #2
0
def test_cli(loop, app, sanic_client):
    global username
    while username is None:
        i = random.randint(1, 10000)
        username = f"amichay.oren+{i}@gmail.com"
        if User.username_exists(username):
            username = None

    return loop.run_until_complete(sanic_client(app))
Beispiel #3
0
def retrieve_user(request, *args, **kwargs):
    if "user_id" in kwargs:
        user_id = kwargs.get("user_id")
    else:
        if "payload" in kwargs:
            payload = kwargs.get("payload")
        else:
            payload = request.app.auth.extract_payload(request)
        user_id = payload.get("user_id")

    return User.get_by_user_id(user_id)
Beispiel #4
0
async def test_positive_register_w_email(test_cli):
    global username
    username = None
    while username is None:
        i = random.randint(1, 10000)
        username = f"amichay.oren+{i}@gmail.com"
        if User.username_exists(username):
            username = None

    data = {"username": username, "password": "******", "email": username}
    resp = await test_cli.post("/users", data=json.dumps(data))
    assert resp.status == 201
Beispiel #5
0
async def delete_user(request, *args, **kwargs):
    try:
        requested_user_id = int(request.path.split("/")[2])
    except ValueError as e:
        raise InvalidUsage(e)

    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")

    user = User.get_by_user_id(requested_user_id)
    if user is None:
        raise InvalidUsage("invalid user")

    if (
        "admin" not in user_from_token.scopes
        and "manager" not in user_from_token.scopes
    ):
        if requested_user_id != user_from_token.user_id:
            raise Forbidden(f"user can only update self")

    user = User.get_by_user_id(requested_user_id)
    if not user:
        raise InvalidUsage("invalid parameter")

    if (
        "manager" in user_from_token.scopes
        and "admin" not in user_from_token.scopes
        and ("manager" in user.scopes or "admin" in user.scopes)
    ):
        if requested_user_id != user_from_token.user_id:
            raise Forbidden(f"manager can only update manager")

    user.expire(user_from_token.user_id)

    return response.HTTPResponse(status=204)
Beispiel #6
0
async def register(request, *args, **kwargs):
    if (
        request.json is None
        or "username" not in request.json
        or "password" not in request.json
    ):
        raise InvalidUsage("invalid payload (should be {username, password})")

    password = request.json["password"]
    if not password_validator(password):
        raise InvalidUsage("password does not match minimum requirements")

    username = request.json["username"]
    if User.username_exists(username):
        raise Conflict(f"username {username} already exists")

    email = request.json["email"] if "email" in request.json else None
    name = request.json["name"] if "name" in request.json else None
    user = User(
        None, username, encrypt(request.json["password"]), ["user"], email, name
    )
    user.save()

    return response.HTTPResponse(status=201)
async def test_positive_get_users_by_manager(test_cli):
    # check who i am
    global access_token
    headers = {"Authorization": f"Bearer {access_token}"}
    resp = await test_cli.get("/auth/me", headers=headers)
    resp_json = await resp.json()
    print(resp_json)
    assert resp.status == 200
    my_user_id = resp_json["me"]["user_id"]

    # promote to manager
    data = {"scopes": ["user", "manager"]}
    headers = {"Authorization": f"Bearer {access_token}"}
    resp = await test_cli.patch(f"/users/{my_user_id}/scopes",
                                headers=headers,
                                data=json.dumps(data))
    assert resp.status == 204

    # re-login to get access token w/ new scope
    data = {"username": username, "password": "******"}
    resp = await test_cli.post("/auth", data=json.dumps(data))
    resp_json = await resp.json()
    print(resp_json)
    access_token = resp_json["access_token"]
    refresh_token = resp_json["refresh_token"]
    assert access_token is not None
    assert refresh_token is not None
    assert resp.status == 200

    # get users
    headers = {"Authorization": f"Bearer {access_token}"}
    resp = await test_cli.get("/users", headers=headers)
    resp_json = await resp.json()

    print(resp_json)
    for row in resp_json:
        user = User(
            user_id=row["user_id"],
            username=row["username"],
            hashed_password=row["hashed_password"],
            scopes=row["scopes"],
            email=row["email"],
            name=row["name"],
        )
        assert False == ("manager" in user.scopes or "admin" in user.scopes)

    assert resp.status == 200
Beispiel #8
0
async def update_user(request, *args, **kwargs):
    if request.json is None:
        raise InvalidUsage("invalid payload (empty payload not allowed)")
    try:
        requested_user_id = int(request.path.split("/")[2])
    except ValueError as e:
        raise InvalidUsage(e)

    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")

    if (
        "admin" not in user_from_token.scopes
        and "manager" not in user_from_token.scopes
    ):
        if requested_user_id != user_from_token.user_id:
            raise Forbidden(f"user can only update self")

    user = User.get_by_user_id(requested_user_id)
    if not user:
        raise InvalidUsage("invalid parameter")

    if (
        "manager" in user_from_token.scopes
        and "admin" not in user_from_token.scopes
        and ("manager" in user.scopes or "admin" in user.scopes)
    ):
        if requested_user_id != user_from_token.user_id:
            raise Forbidden(f"manager can only update manager")

    if "password" in request.json:
        password = request.json["password"]
        if not password_validator(password):
            raise InvalidUsage("password does not match minimum requirements")

        user.update_password(encrypt(password))
    if "email" in request.json:
        user.update_email(request.json["email"])
    if "name" in request.json:
        user.update_name(request.json["name"])

    user.save(modifying_user_id=user_from_token.user_id)

    return response.HTTPResponse(status=204)
Beispiel #9
0
async def authenticate(request, *args, **kwargs):
    if request.json is None:
        raise exceptions.AuthenticationFailed("missing payload")

    username = request.json.get("username", None)
    password = request.json.get("password", None)

    if not username or not password:
        raise exceptions.AuthenticationFailed("Missing username or password.")

    user = User.get_by_username(username)
    if user is None:
        raise exceptions.AuthenticationFailed("User not found.")

    if not bcrypt.checkpw(password.encode("utf-8"),
                          user.hashed_password.encode("utf-8")):
        raise exceptions.AuthenticationFailed("Password is incorrect.")

    return user
Beispiel #10
0
async def get_users(request, *args, **kwargs):
    page = int(request.args["page"][0]) if "page" in request.args else 0
    limit = int(request.args["count"][0]) if "count" in request.args else 10

    if page < 0 or limit <= 0:
        raise InvalidUsage("invalid paging (page >= 0 and count > 0)")

    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")
    user_id = user_from_token.user_id
    user = User.get_by_user_id(user_id)

    try:
        rc = user.get_users(page, limit)
    except Exception as e:
        raise InvalidUsage(e)

    return response.json(rc, status=200)
Beispiel #11
0
async def update_user_scope(request, *args, **kwargs):
    if request.json is None:
        raise InvalidUsage("invalid payload (empty payload not allowed)")

    try:
        requested_user_id = int(request.path.split("/")[2])
    except ValueError as e:
        raise InvalidUsage(e)

    user_from_token = retrieve_user(request, args, kwargs)
    if user_from_token is None:
        raise InvalidUsage("invalid parameter (maybe expired?)")

    user = User.get_by_user_id(requested_user_id)
    if user is None:
        raise InvalidUsage("invalid user")

    if "scopes" in request.json:
        print(request.json)
        user.update_scopes(request.json["scopes"])

    user.save(modifying_user_id=user_from_token.user_id)

    return response.HTTPResponse(status=204)
Beispiel #12
0
async def test_positive_admin_update_user(test_cli):
    global access_token
    # check who i am
    headers = {"Authorization": f"Bearer {access_token}"}
    resp = await test_cli.get("/auth/me", headers=headers)
    resp_json = await resp.json()
    print(resp_json)
    assert resp.status == 200

    # update me
    my_user_id = resp_json["me"]["user_id"]
    data = {"scopes": ["user", "manager", "admin"]}
    headers = {"Authorization": f"Bearer {access_token}"}
    resp = await test_cli.patch(f"/users/{my_user_id}/scopes",
                                headers=headers,
                                data=json.dumps(data))
    assert resp.status == 204
    manager_access_token = access_token

    # register second
    global username
    username = None
    while username is None:
        i = random.randint(1, 10000)
        username = f"amichay.oren+{i}"
        if User.username_exists(username):
            username = None

    data = {
        "username": username,
        "password": "******",
        "name": "Amichay Oren",
        "email": f"{username}@gmail.com",
    }
    resp = await test_cli.post("/users", data=json.dumps(data))
    assert resp.status == 201

    # login second
    data = {"username": username, "password": "******"}
    resp = await test_cli.post("/auth", data=json.dumps(data))
    resp_json = await resp.json()
    print(resp_json)
    access_token = resp_json["access_token"]
    refresh_token = resp_json["refresh_token"]
    assert access_token is not None
    assert refresh_token is not None
    assert resp.status == 200

    # check who is second
    headers = {"Authorization": f"Bearer {access_token}"}
    resp = await test_cli.get("/auth/me", headers=headers)
    resp_json = await resp.json()
    print(resp_json)
    assert resp.status == 200
    new_manager_user_id = resp_json["me"]["user_id"]

    # first admin update second user
    new_name = "some new name"
    data = {"name": new_name}
    headers = {"Authorization": f"Bearer {manager_access_token}"}
    resp = await test_cli.patch(f"/users/{new_manager_user_id}",
                                headers=headers,
                                data=json.dumps(data))
    assert resp.status == 204