Ejemplo n.º 1
0
    async def test_new_user(self, user_manager_oauth: UserManagerMock):
        oauth_account = models.BaseOAuthAccount(
            oauth_name="service1",
            access_token="TOKEN",
            expires_at=1579000751,
            account_id="new_user_oauth1",
            account_email="*****@*****.**",
        )
        user = cast(UserDBOAuth, await
                    user_manager_oauth.oauth_callback(oauth_account))

        assert user.email == "*****@*****.**"
        assert len(user.oauth_accounts) == 1
        assert user.oauth_accounts[0].id == oauth_account.id

        assert user_manager_oauth.on_after_register.called is True
Ejemplo n.º 2
0
    async def test_existing_user_with_oauth(
            self, user_manager_oauth: UserManagerMock,
            user_oauth: UserDBOAuth):
        oauth_account = models.BaseOAuthAccount(
            **user_oauth.oauth_accounts[0].dict(
                exclude={"id", "access_token"}),
            access_token="UPDATED_TOKEN")
        user = cast(UserDBOAuth, await
                    user_manager_oauth.oauth_callback(oauth_account))

        assert user.id == user_oauth.id
        assert len(user.oauth_accounts) == 2
        assert user.oauth_accounts[0].oauth_name == "service1"
        assert user.oauth_accounts[0].access_token == "UPDATED_TOKEN"
        assert user.oauth_accounts[1].access_token == "TOKEN"
        assert user.oauth_accounts[1].oauth_name == "service2"

        assert user_manager_oauth.on_after_register.called is False
Ejemplo n.º 3
0
    async def test_existing_user_without_oauth(
            self, user_manager_oauth: UserManagerMock,
            superuser_oauth: UserDBOAuth):
        oauth_account = models.BaseOAuthAccount(
            oauth_name="service1",
            access_token="TOKEN",
            expires_at=1579000751,
            account_id="superuser_oauth1",
            account_email=superuser_oauth.email,
        )
        user = cast(UserDBOAuth, await
                    user_manager_oauth.oauth_callback(oauth_account))

        assert user.id == superuser_oauth.id
        assert len(user.oauth_accounts) == 1
        assert user.oauth_accounts[0].id == oauth_account.id

        assert user_manager_oauth.on_after_register.called is False
Ejemplo n.º 4
0
    async def callback(
        request: Request,
        response: Response,
        access_token_state: Tuple[OAuth2Token, str] = Depends(
            oauth2_authorize_callback
        ),
        user_manager: BaseUserManager[models.UC, models.UD] = Depends(get_user_manager),
        strategy: Strategy[models.UC, models.UD] = Depends(backend.get_strategy),
    ):
        token, state = access_token_state
        account_id, account_email = await oauth_client.get_id_email(
            token["access_token"]
        )

        try:
            decode_jwt(state, state_secret, [STATE_TOKEN_AUDIENCE])
        except jwt.DecodeError:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        new_oauth_account = models.BaseOAuthAccount(
            oauth_name=oauth_client.name,
            access_token=token["access_token"],
            expires_at=token.get("expires_at"),
            refresh_token=token.get("refresh_token"),
            account_id=account_id,
            account_email=account_email,
        )

        user = await user_manager.oauth_callback(new_oauth_account, request)

        if not user.is_active:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.LOGIN_BAD_CREDENTIALS,
            )

        # Authenticate
        return await backend.login(strategy, user, response)
Ejemplo n.º 5
0
    async def callback(
            request: Request,
            response: Response,
            access_token_state=Depends(oauth2_authorize_callback),
    ):
        token, state = access_token_state
        account_id, account_email = await oauth_client.get_id_email(
            token["access_token"])

        try:
            state_data = decode_state_token(state, state_secret)
        except jwt.DecodeError:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)

        user = await user_db.get_by_oauth_account(oauth_client.name,
                                                  account_id)

        new_oauth_account = models.BaseOAuthAccount(
            oauth_name=oauth_client.name,
            access_token=token["access_token"],
            expires_at=token.get("expires_at"),
            refresh_token=token.get("refresh_token"),
            account_id=account_id,
            account_email=account_email,
        )

        if not user:
            user = await user_db.get_by_email(account_email)
            if user:
                # Link account
                user.oauth_accounts.append(new_oauth_account)  # type: ignore
                await user_db.update(user)
            else:
                # Create account
                password = generate_password()
                user = user_db_model(
                    email=account_email,
                    hashed_password=get_password_hash(password),
                    oauth_accounts=[new_oauth_account],
                )
                await user_db.create(user)
                if after_register:
                    await run_handler(after_register, user, request)
        else:
            # Update oauth
            updated_oauth_accounts = []
            for oauth_account in user.oauth_accounts:  # type: ignore
                if oauth_account.account_id == account_id:
                    updated_oauth_accounts.append(new_oauth_account)
                else:
                    updated_oauth_accounts.append(oauth_account)
            user.oauth_accounts = updated_oauth_accounts  # type: ignore
            await user_db.update(user)

        if not user.is_active:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ErrorCode.LOGIN_BAD_CREDENTIALS,
            )

        # Authenticate
        for backend in authenticator.backends:
            if backend.name == state_data["authentication_backend"]:
                return await backend.get_login_response(
                    cast(models.BaseUserDB, user), response)