示例#1
0
async def test_request_email_confirmation_confirmed():
    auth_service = AuthService()
    auth_service._user = User(2, "user", False)
    with pytest.raises(HTTPException) as e:
        await auth_service.request_email_confirmation()

    assert e.type is HTTPException
    assert e.value.args[0] == 400
示例#2
0
async def test_get_email_confirmation_status(user: User, email: str,
                                             confirmed: bool):
    auth_service = AuthService()
    auth_service._user = user
    status = await auth_service.get_email_confirmation_status()
    assert status.get("email") == email
    assert status.get("confirmed") == confirmed

    auth_service._user = user
    status = await auth_service.get_email_confirmation_status()
    assert status.get("email") == email
    assert status.get("confirmed") is confirmed
示例#3
0
def auth_service_setup():
    AuthService.setup(
        UsersRepo(MockDatabaseBackend("test"), MockCacheBackend(), []),
        auth_backend,
        False,
        "RU",
        "http://127.0.0.1",
        "127.0.0.1",
        RECAPTCHA_SECRET,
        None,
        None,
        None,
        None,
        None,
    )
示例#4
0
    async def register(*, request: Request, response: Response):
        data = await request.json()
        service = AuthService()

        tokens = await service.register(data)
        set_tokens_in_response(response, tokens)
        return None
示例#5
0
async def test_login(login: str, password: str):
    auth_service = AuthService()
    tokens = await auth_service.login({
        "login": login,
        "password": password
    }, "127.0.0.1")
    # TODO
    assert isinstance(tokens, dict)
示例#6
0
    async def login(*, request: Request, response: Response):
        data = await request.json()
        service = AuthService()

        ip = request.client.host

        tokens = await service.login(data, ip)
        set_tokens_in_response(response, tokens)
        return None
示例#7
0
async def test_refresh_access_token() -> str:
    auth_service = AuthService()
    refresh_token = auth_backend.create_refresh_token({
        "id": 1,
        "username": "******",
        "permissions": [],
        "type": "refresh",
    })
    access_token = await auth_service.refresh_access_token(refresh_token)
    assert isinstance(access_token, str)
示例#8
0
 async def change_username(
         *,
         id: int,
         username: str = Body("", embed=True),
         user: User = Depends(get_authenticated_user),
 ):
     service = AuthService(user)
     if user.id == id or user.is_admin:
         return await service.change_username(id, username)
     else:
         raise HTTPException(403)
示例#9
0
    async def refresh_access_token(
        *,
        request: Request,
        response: Response,
    ):
        service = AuthService()
        refresh_token = request.cookies.get(refresh_cookie_name)
        if refresh_token is None:
            raise HTTPException(401)

        access_token = await service.refresh_access_token(refresh_token)
        set_access_token_in_response(response, access_token)
        return {"access": access_token}
示例#10
0
async def test_confirm_email():
    auth_service = AuthService()
    email = "*****@*****.**"
    token = create_random_string()
    token_hash = hash_string(token)
    await auth_service._repo.request_email_confirmation(email, token_hash)

    with pytest.raises(HTTPException) as e:
        await auth_service.confirm_email("wrongtoken")

    assert e.type is HTTPException
    assert e.value.args[0] == 403  # TODO: 400 maybe

    await auth_service.confirm_email(token)

    item = await auth_service._repo.get_by_email(email)
    assert item.get("confirmed")
示例#11
0
async def test_change_username():
    auth_service = AuthService(User(1, "admin", True))
    await auth_service.change_username(2, "newusername")  # admin
    assert await auth_service._repo.get_by_username("newusername") is not None
    assert await auth_service._repo.get_by_username("username") is None

    with pytest.raises(HTTPException) as e:
        await auth_service.change_username(2, "admin")  # exists

    assert e.type is HTTPException
    assert e.value.args[0] == 400

    with pytest.raises(HTTPException) as e:
        await auth_service.change_username(1, "admin")  # same

    assert e.type is HTTPException
    assert e.value.args[0] == 400

    await auth_service.change_username(1, "newadmin")  # own
    assert await auth_service._repo.get_by_username("newadmin") is not None
    assert await auth_service._repo.get_by_username("admin") is None
示例#12
0
async def test_register(
    email: str,
    username: str,
    password1: str,
    password2: str,
    valid_data: bool,
    captcha: str,
    valid_captcha: bool,
):
    auth_service = AuthService()
    with mock.patch(
            "fastapi_auth.services.auth.validate_captcha",
            mock.AsyncMock(return_value=valid_captcha),
    ) as mock_validate_captcha:
        if not valid_captcha:
            with pytest.raises(HTTPException) as e:
                await auth_service.register({
                    "email": email,
                    "username": username,
                    "password1": password1,
                    "password2": password2,
                    "captcha": captcha,
                })
            assert e.type is HTTPException
            assert e.value.args[0] == 400
        else:
            res = await auth_service.register({
                "email": email,
                "username": username,
                "password1": password1,
                "password2": password2,
                "captcha": captcha,
            })
            assert isinstance(res, dict)
            assert isinstance(res.get("access"), str)
            assert isinstance(res.get("refresh"), str)

        mock_validate_captcha.assert_awaited_once_with(captcha,
                                                       RECAPTCHA_SECRET)
示例#13
0
async def test_request_email_confirmation():
    auth_service = AuthService()
    auth_service._user = User(3, "anotheruser", False)
    res = await auth_service.request_email_confirmation()
    assert res is None
示例#14
0
def get_router(
    repo: UsersRepo,
    auth_backend: JWTBackend,
    get_authenticated_user: Callable,
    debug: bool,
    language: str,
    base_url: str,
    site: str,
    access_cookie_name: str,
    refresh_cookie_name: str,
    access_expiration: int,
    refresh_expiration: int,
    recaptcha_secret: str,
    smtp_username: str,
    smtp_password: str,
    smtp_host: str,
    smtp_tls: int,
    display_name: str,
) -> APIRouter:

    AuthService.setup(
        repo,
        auth_backend,
        debug,
        language,
        base_url,
        site,
        recaptcha_secret,
        smtp_username,
        smtp_password,
        smtp_host,
        smtp_tls,
        display_name,
    )

    def set_access_token_in_response(response, token: str) -> None:
        response.set_cookie(
            key=access_cookie_name,
            value=token,
            secure=not debug,
            httponly=True,
            max_age=access_expiration,
        )

    def set_refresh_token_in_response(response, token: str) -> None:
        response.set_cookie(
            key=refresh_cookie_name,
            value=token,
            secure=not debug,
            httponly=True,
            max_age=refresh_expiration,
        )

    def set_tokens_in_response(response, tokens: Dict[str, str]) -> None:
        access_token = tokens.get("access")
        refresh_token = tokens.get("refresh")
        set_access_token_in_response(response, access_token)
        set_refresh_token_in_response(response, refresh_token)

    router = APIRouter()

    @router.post("/register", name="auth:register")
    async def register(*, request: Request, response: Response):
        data = await request.json()
        service = AuthService()

        tokens = await service.register(data)
        set_tokens_in_response(response, tokens)
        return None

    @router.post("/login", name="auth:login")
    async def login(*, request: Request, response: Response):
        data = await request.json()
        service = AuthService()

        ip = request.client.host

        tokens = await service.login(data, ip)
        set_tokens_in_response(response, tokens)
        return None

    @router.post("/logout", name="auth:logout")
    async def logout(*, response: Response):
        response.delete_cookie(access_cookie_name)
        response.delete_cookie(refresh_cookie_name)
        return None

    @router.post("/token", name="auth:token")
    async def token(*, user: User = Depends(get_authenticated_user)):
        return user.data

    @router.post("/token/refresh", name="auth:refresh_access_token")
    async def refresh_access_token(
        *,
        request: Request,
        response: Response,
    ):
        service = AuthService()
        refresh_token = request.cookies.get(refresh_cookie_name)
        if refresh_token is None:
            raise HTTPException(401)

        access_token = await service.refresh_access_token(refresh_token)
        set_access_token_in_response(response, access_token)
        return {"access": access_token}

    @router.get("/confirm", name="auth:get_email_confirmation_status")
    async def get_email_confirmation_status(
        *, user: User = Depends(get_authenticated_user)):
        service = AuthService(user)
        return await service.get_email_confirmation_status()

    @router.post("/confirm", name="auth:request_email_confirmation")
    async def request_email_confirmation(
        *, user: User = Depends(get_authenticated_user)):
        service = AuthService(user)
        return await service.request_email_confirmation()

    @router.post("/confirm/{token}", name="auth:confirm_email")
    async def confirm_email(*, token: str):
        service = AuthService()
        return await service.confirm_email(token)

    @router.post("/{id}/change_username", name="auth:change_username")
    async def change_username(
            *,
            id: int,
            username: str = Body("", embed=True),
            user: User = Depends(get_authenticated_user),
    ):
        service = AuthService(user)
        if user.id == id or user.is_admin:
            return await service.change_username(id, username)
        else:
            raise HTTPException(403)

    return router
示例#15
0
 async def confirm_email(*, token: str):
     service = AuthService()
     return await service.confirm_email(token)
示例#16
0
 async def request_email_confirmation(
     *, user: User = Depends(get_authenticated_user)):
     service = AuthService(user)
     return await service.request_email_confirmation()
示例#17
0
 async def get_email_confirmation_status(
     *, user: User = Depends(get_authenticated_user)):
     service = AuthService(user)
     return await service.get_email_confirmation_status()