Пример #1
0
async def test_update_one_user_as_supervisor(users, supervisor1_client):
    new_changes = {
        "full_name": "this name surely doesnt exist",
        "password": "******",
    }

    # With id
    res = await supervisor1_client.patch("/users/{}".format(users[0]["id"]),
                                         json=new_changes)
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    updated_user = await get_one(User, internal_id=1)
    updated_user = updated_user.to_dict()

    ## Assert the new password has been updated
    assert profile_created_from_origin(
        {
            **body["data"], "password": hash_password(new_changes["password"])
        },
        updated_user,
    )

    # User doesnt exist
    res = await supervisor1_client.patch("/users/{}".format("9" * 32),
                                         json=new_changes)
    assert res.status == 404

    # Update to a weak password
    new_changes = {"password": "******"}
    res = await supervisor1_client.patch("/users/{}".format(users[1]["id"]),
                                         json=new_changes)
    assert res.status == 400
Пример #2
0
async def test_update_anonymous_as_self(visitors, anonymous1_client):
    new_changes = {
        "name": "this name surely doesnt exist",
        "password": "******",
    }

    # With id
    res = await anonymous1_client.patch("/visitors/{}".format(
        visitors[-4]["id"]),
                                        json=new_changes)
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    updated_user = await get_one(Visitor, id=visitors[-4]["id"])
    updated_user = updated_user.to_dict()

    ## Assert the new password has been updated
    assert profile_created_from_origin(
        {
            **body["data"], "password": hash_password(new_changes["password"])
        },
        updated_user,
        ignore={"updated_at"},
    )
Пример #3
0
    async def modify(cls, get_kwargs, update_kwargs):
        if "password" in update_kwargs:
            password = update_kwargs["password"]
            validate_password_strength(password)
            update_kwargs["password"] = hash_password(password)

        return await super(BaseUser, cls).modify(get_kwargs, update_kwargs)
Пример #4
0
    async def add(cls, password=None, **kwargs):
        # Follow guidelines from OWASP
        # https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html
        if password:
            validate_password_strength(password)
            password = hash_password(password)

        return await super(BaseUser, cls).add(password=password, **kwargs)
Пример #5
0
async def setup_db():
    "Re-setup the DB"
    # Create a test org
    org_data = _orgs[0]
    org = await Organisation(**org_data).create()

    # Register the global settings
    for setting in _settings:
        try:
            await Setting(**setting).create()
        except UniqueViolationError:
            pass

    # Register the user roles
    for user_role in _user_roles:
        try:
            await UserRole(**user_role).create()
        except UniqueViolationError:
            pass

    # Register the permissions
    for key, roles in DEFAULT_PERMISSIONS.items():
        for role_id in roles:
            try:
                await RolePermission(**{"name": key, "role_id": role_id}).create()
            except UniqueViolationError:
                pass

    # Register all users under the same org
    for user in _users:
        _user = deepcopy(user)
        _user["password"] = hash_password(_user["password"])
        await User(**_user, organisation_id=org.id).create()

    # Register the visitors
    for visitor in _visitors:
        _visitor = deepcopy(visitor)

        # Anonymous users don't have passwords
        if "password" in _visitor:
            _visitor["password"] = hash_password(_visitor["password"])
        await Visitor(**_visitor).create()
Пример #6
0
async def test_update_user_as_admin(users, admin1_client):
    new_changes = {
        "full_name": "this name surely doesnt exist",
        "password": "******",
    }
    res = await admin1_client.patch("/users/{}".format(users[5]["id"]),
                                    json=new_changes)
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    updated_user = await get_one(User, internal_id=6)
    updated_user = updated_user.to_dict()

    ## Assert the new password has been updated
    assert profile_created_from_origin(
        {
            **body["data"], "password": hash_password(new_changes["password"])
        },
        updated_user,
    )

    # Admin can update supervisor
    res = await admin1_client.patch("/users/{}".format(users[-3]["id"]),
                                    json=new_changes)
    assert res.status == 200

    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], dict)
    updated_user = await get_one(User, id=users[-3]["id"])
    updated_user = updated_user.to_dict()

    ## Assert the new password has been updated
    assert profile_created_from_origin(
        {
            **body["data"], "password": hash_password(new_changes["password"])
        },
        updated_user,
    )
Пример #7
0
    async def login(cls,
                    email=None,
                    password=None,
                    *,
                    is_anonymous=False,
                    **kwargs):
        user = None
        if not is_anonymous:
            if not email:
                raise InvalidUsage("Missing field 'email' in request's body.")
            if not password:
                raise InvalidUsage(
                    "Missing field 'password' in request's body.")

            password = hash_password(password)
            try:
                user = await cls.get(email=email, password=password, **kwargs)
            except NotFound:
                pass

            if not user:
                raise LoginFailureError()

            # Invalidate the staff if he is disabled
            if "role_id" in user and user["disabled"]:
                raise Unauthorized(
                    "Your account have been disabled. Please contact your supervisor."
                )
        else:  # Anonymous login
            kwargs["is_anonymous"] = True
            user = await cls.add(**kwargs)

        # Only store minimum info for user
        fields = {
            "id",
            "full_name",
            "display_name",
            "name",
            "email",
            "role_id",
            "organisation_id",
            "is_anonymous",
            "disabled",
        }
        for key in list(user.keys()):
            if key not in fields:
                user.pop(key, None)

        return user
Пример #8
0
async def test_update_last_seen_message_of_staff(supervisor1_client):
    # Create a lot more visitors to test
    visitors = [get_fake_visitor() for _ in range(3)]
    for visitor in visitors:
        _visitor = deepcopy(visitor)

        # Anonymous users don't have passwords
        if "password" in _visitor:
            _visitor["password"] = hash_password(_visitor["password"])
        await Visitor(**_visitor).create()

    # Create some dummy chat messages
    created_at = 1
    chat_messages = {}
    for visitor in visitors[::-1]:
        chat = await Chat.add(visitor_id=visitor["id"])
        for sequence_num in range(4):
            content = {"content": fake.sentence(nb_words=10)}
            chat_msg = {
                "chat_id": chat["id"],
                "sequence_num": sequence_num,
                "content": content,
                "sender": None,
                "created_at": created_at,
            }
            created_at += 1
            created_msg = await ChatMessage.add(**chat_msg)
            chat_messages.setdefault(chat["id"], []).append(created_msg)

    for chat_id, value in chat_messages.items():
        chat = await Chat.get(id=chat_id)
        res = await supervisor1_client.patch(
            "/visitors/{}/last_seen".format(chat["visitor_id"]),
            json={"last_seen_msg_id": value[2]["id"]},
        )
        assert res.status == 200
        body = await res.json()
        assert "data" in body
        assert isinstance(body["data"], dict)
        assert body["data"]["last_seen_msg_id"] == value[2]["id"]
Пример #9
0
async def test_get_visitors_most_recent(users, supervisor1_client):
    # Create a lot more visitors to test
    visitors = [get_fake_visitor() for _ in range(32)]
    for visitor in visitors:
        _visitor = deepcopy(visitor)

        # Anonymous users don't have passwords
        if "password" in _visitor:
            _visitor["password"] = hash_password(_visitor["password"])
        await Visitor(**_visitor).create()

    # Create some dummy chat messages
    created_at = 1
    staff = users[-5]
    for visitor in visitors[::-1]:
        chat = await Chat.add(visitor_id=visitor["id"])
        for sequence_num in range(3):
            content = {"content": fake.sentence(nb_words=10)}
            chat_msg = {
                "chat_id": chat["id"],
                "sequence_num": sequence_num,
                "content": content,
                "sender": None,
                "created_at": created_at,
            }
            created_at += 1
            await ChatMessage.add(**chat_msg)

        # Let a staff send a message, as staffs can only fetch visitors
        # that chatted with the staffs from his org
        await ChatMessage.add(
            **{
                "chat_id": chat["id"],
                "sequence_num": sequence_num + 1,
                "content": {
                    "content": fake.sentence(nb_words=10)
                },
                "sender": staff["id"],
                "created_at": created_at,
            })

    # Get the most recent visitors that chatted with the staffs from org
    res = await supervisor1_client.get("/visitors/most_recent")
    assert res.status == 200
    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15
    assert "links" in body and "next" in body["links"]
    for expected, actual in zip(visitors, body["data"]):
        assert profile_created_from_origin(expected, actual)

    # Ensure that the next links work as well
    next_page_link = get_next_page_link(body)
    res = await supervisor1_client.get(next_page_link)
    assert res.status == 200
    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 15
    assert "links" in body and "next" in body["links"]
    for expected, actual in zip(visitors[15:], body["data"]):
        assert profile_created_from_origin(expected, actual)

    # Last page
    next_page_link = get_next_page_link(body)
    res = await supervisor1_client.get(next_page_link)
    assert res.status == 200
    assert res.status == 200
    body = await res.json()
    assert "data" in body
    assert isinstance(body["data"], list)
    assert len(body["data"]) == 2
    assert "links" in body and "next" in body["links"]
    for expected, actual in zip(visitors[30:], body["data"]):
        assert profile_created_from_origin(expected, actual)