0
votes

How to integrate Sonata User Bundle with HWIOAuthBundle. At HWIOAuthBundle the doc is FOSUserBundle. But there is no doc for SonataUserBundle in NET. I googled net and found nothing.

As per HWIOAuthBundle doc I created ,

Application\Sonata\UserBundle\Entity\User

/**
     * @ORM\Column(name="facebook_id", type="string", length=255, nullable=true)
     */
    private $facebookId;

    private $facebookAccessToken;
/**
     * @param string $facebookId
     * @return User
     */
    public function setFacebookId($facebookId)
    {
        $this->facebookId = $facebookId;

        return $this;
    }

    /**
     * @return string
     */
    public function getFacebookId()
    {
        return $this->facebookId;
    }

    /**
     * @param string $facebookAccessToken
     * @return User
     */
    public function setFacebookAccessToken($facebookAccessToken)
    {
        $this->facebookAccessToken = $facebookAccessToken;

        return $this;
    }

    /**
     * @return string
     */
    public function getFacebookAccessToken()
    {
        return $this->facebookAccessToken;
    }

My Provider class (from net)

public function connect(UserInterface $user, UserResponseInterface $response) {
        $property = $this->getProperty($response);
        $username = $response->getUsername();
        $service = $response->getResourceOwner()->getName();
        $setter = 'set' . ucfirst($service);
        $setter_id = $setter . 'Id';
        $setter_token = $setter . 'AccessToken';
        if (null !== $previousUser = $this->userManager->findUserBy([$property => $username])) {
            $previousUser->$setter_id(null);
            $previousUser->$setter_token(null);
            $this->userManager->updateUser($previousUser);
        }
        $user->$setter_id($username);
        $user->$setter_token($response->getAccessToken());
        $this->userManager->updateUser($user);
    }

    public function loadUserByOAuthUserResponse(UserResponseInterface $response) {
        $username = $response->getUsername();
        $user = $this->userManager->findUserBy([$this->getProperty($response) => $username]);
        if (null === $user) {
            $service = $response->getResourceOwner()->getName();
            $setter = 'set' . ucfirst($service);
            $setter_id = $setter . 'Id';
            $setter_token = $setter . 'AccessToken';
            $user = $this->userManager->createUser();
            $user->$setter_id($username);
            $user->$setter_token($response->getAccessToken());
            $user->setUsername($username);
            $user->setEmail($response->getEmail());
            $user->setPlainPassword($response->getAccessToken());
            $user->setEnabled(TRUE);
            $this->userManager->updateUser($user);
            return $user;
        }
        $user = parent::loadUserByOAuthUserResponse($response);
        $serviceName = $response->getResourceOwner()->getName();
        $setter = 'set' . ucfirst($serviceName) . 'AccessToken';
        $user->$setter($response->getAccessToken());
        return $user;
    }

But I get error

Unrecognized field: facebookID

I also changed $setter_id = $setter . 'Id'; to $setter_id = $setter . 'Uid'; But still error. as per sonata user entity

UPDATE 01:

At Application\Sonata\UserBundle\Entity\User I changed $facebookID (and all its related...). Then I get error invalid password.

1

1 Answers

1
votes

I got answer from this location. It has only for google But i added for facebook also. Using FOSUserBundle,

http://inchoo.net/dev-talk/symfony-hwioauthbundle-and-google-sign-in/

<?php

/*
 * Copyright (C) 2016 sudhakar.
 * http://www.featuriz.com/licenses/LICENSE-2.0
 */

namespace AppBundle\Service;

use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use Application\Sonata\UserBundle\Entity\User;

/**
 * Description of OAuthProvider
 *
 * @author sudhakar
 */
class OAuthProvider extends OAuthUserProvider {

    protected $session, $doctrine, $admins, $oro = 'facebookUid';

    public function __construct($session, $doctrine, $service_container) {
        $this->session = $session;
        $this->doctrine = $doctrine;
        $this->container = $service_container;
    }

    public function loadUserByUsername($username) {

        $qb = $this->doctrine->getManager()->createQueryBuilder();
        $qb->select('u')->from('ApplicationSonataUserBundle:User', 'u')->where('u.' . $this->oro . ' = :oid')->setParameter('oid', $username)->setMaxResults(1);
        $result = $qb->getQuery()->getResult();

        if (count($result)) {
            return $result[0];
        } else {
            return new User();
        }
    }

    public function loadUserByOAuthUserResponse(UserResponseInterface $response) {
        $ro = $response->getResourceOwner()->getName();
        //Data from Google response
        $oauth_id = $response->getUsername(); /* An ID like: 112259658235204980084 */
        $email = $response->getEmail();
        $nickname = $response->getNickname();
        $realname = $response->getRealName();
        $avatar = $response->getProfilePicture();

        //set data in session
        $this->session->set('email', $email);
        $this->session->set('nickname', $nickname);
        $this->session->set('realname', $realname);
        $this->session->set('avatar', $avatar);

        //Check if this Google user already exists in our app DB
        $qb = $this->doctrine->getManager()->createQueryBuilder();
        $this->oro = 'gplusUid';
        if ($ro == 'google') {
            $this->oro = 'gplusUid';
        } elseif ($ro == 'facebook') {
            $this->oro = 'facebookUid';
        }
        $qb->select('u')->from('ApplicationSonataUserBundle:User', 'u')->where('u.' . $this->oro . ' = :oid')->setParameter('oid', $oauth_id)->setMaxResults(1);
        $result = $qb->getQuery()->getResult();

        //add to database if doesn't exists
        if (!count($result)) {
//            $user = new User();
//            $user->setUsername($google_id);
//            $user->setRealname($realname);
//            $user->setNickname($nickname);
//            $user->setEmail($email);
//            $user->setGoogleId($google_id);
//            //$user->setRoles('ROLE_USER');
//            //Set some wild random pass since its irrelevant, this is Google login
//            $factory = $this->container->get('security.encoder_factory');
//            $encoder = $factory->getEncoder($user);
//            $password = $encoder->encodePassword(md5(uniqid()), $user->getSalt());
//            $user->setPassword($password);
//
//            $em = $this->doctrine->getManager();
//            $em->persist($user);
//            $em->flush();
        } else {
            $user = $result[0]; /* return User */
        }

        //set id
        $this->session->set('id', $user->getId());

        return $this->loadUserByUsername($response->getUsername());
    }

    public function supportsClass($class) {
        return $class === 'Application\\Sonata\\UserBundle\\Entity\\User';
    }

}

I need to only login. Not new user Register, that's why I ignored in code.