Exemplo n.º 1
0
    def authenticate_facebook(
        self,
        session: Session,
        facebook_user_id: str,
        access_token: str,
        email: str,
        first_name: str,
        last_name: str,
        role: UserRole,
        authenticated_user: User = None,
    ):
        user: User = None

        # TODO refactor social account methods into service?
        existing_facebook_social_account: Optional[SocialAccount] = (
            session.query(SocialAccount).filter(
                SocialAccount.account_type == SocialAccountType.FACEBOOK).
            filter(SocialAccount.account_id == facebook_user_id).one_or_none())

        if not authenticated_user and existing_facebook_social_account:
            # social account exists therefore user exists
            # sing in with facebook
            user: User = existing_facebook_social_account.user
            existing_facebook_social_account.access_token = access_token
            existing_facebook_social_account.account_email = email

        elif not authenticated_user:
            # sign up with facebook
            user_with_email = self.user_service.get_by_email(session, email)
            if user_with_email:
                raise ApplicationError("User exists with this email address")
            user = self.user_service.create(
                session,
                first_name=first_name,
                last_name=last_name,
                email=email,
                email_verified=True,
                role=role,
                commit=False,
            )
            session.flush()
            existing_facebook_social_account = SocialAccount(
                user_id=user.id,
                access_token=access_token,
                account_id=facebook_user_id,
                account_email=email,
                account_type=SocialAccountType.FACEBOOK,
            )
            session.add(existing_facebook_social_account)

        elif not existing_facebook_social_account:
            # link facebook account
            # does user already havea an existing facebook account
            authenticated_users_existing_facebook_account = (
                session.query(SocialAccount).filter(
                    SocialAccount.user_id == authenticated_user.id).filter(
                        SocialAccount.account_type ==
                        SocialAccountType.FACEBOOK).one_or_none())
            if authenticated_users_existing_facebook_account:
                # update the account if yes
                authenticated_users_existing_facebook_account.access_token = (
                    access_token)
                authenticated_users_existing_facebook_account.account_email = email
                authenticated_users_existing_facebook_account.account_id = (
                    facebook_user_id)
            else:
                # create a new one if not.
                existing_facebook_social_account = SocialAccount(
                    user_id=authenticated_user.id,
                    access_token=access_token,
                    account_id=facebook_user_id,
                    account_email=email,
                    account_type=SocialAccountType.FACEBOOK,
                )
                session.add(existing_facebook_social_account)
            user = authenticated_user

        else:
            # update facebook account
            user: User = existing_facebook_social_account.user
            if authenticated_user != user:
                raise ApplicationError(
                    "Facebook Account is linked to another user")
            existing_facebook_social_account.access_token = access_token
            existing_facebook_social_account.account_email = email

        session.commit()
        return util.create_access_token(data={"sub": str(user.id)})