symfony - Symfony2: How to login using OAuth (HWIOAuthBundle) + custom roles (by default and loaded from DB) -


note: questions @ end of text explain in detail context better understanding.

i'm developing symfony2 application consisting of 3 modules:

  1. module students -> needs role role_student
  2. module teachers -> needs role role_teacher
  3. module administrators -> needs role role_admin

the role hierarchy follows:

  • role_teacher: [role_student]
  • role_admin: [role_teacher]

therefore:

a student (with role_student role) can access pages of his/her module, example:

a teacher (with role_teacher role) can access pages of students' module , pages of teachers' module, such as:

an administrator (with role_admin role) can access pages of students' module, pages of teachers' module , admin backend.

the system uses oauth authenticate students , teachers through twitter, using bundle hwioauthbundle (using oauthuserprovider user provider provides bundle).

i've achieved authenticate users but, by default, users automatically authenticated with following roles: [role_user, role_oauth_user]


so here have done. below, i'm going explain want app don't know way:

steps login using oauth:

a user logs in system , automatically:

  • if user not exist in database:
    - save nickname in users table of database.
    - save role role_student (this role default me) in users table of database.
    - authenticate in system using oauth using role_student role.

  • if user exists in database:
    - check role has associated user in database.
    - authenticate user in system using oauth using role associated in database (i.e.: role_student or role_teacher).

the administrator (from administration backend) can see list of nicknames (used twitter saved in database) , assigned roles each nickname. administrator should able change role of users between role_student , role_teacher.


the questions:

  1. how can authenticate user via oauth (hwioauthbundle) role want default (role_student explained above)?

  2. if nickname exists in database role associated (role_student or role_teacher), how can authenticate user via oauth (hwioauthbundle) using role loaded database?

i've been reading lot subject i'm new symfony2 , don't know best , easiest way solve it.

thank in advance!

ps: if have questions or doubts anything, i'll glad explain best possible.

update:

i tried using code in 1 of recent projects , didn't work anymore. reason hwioauthbundle has updated few times , config files not same. put code above login few other social networks in github can find @ hwioauthbundlebyexample.


i have week experience symfony2 , in past days that's working myself. found question today (when still researching).

i'm gonna present had do, based on data, , how did it. after that, i'll try giving key links , hope you'll manage modelate needs.

my app needs facebook login , admin role. because few administrators, need few facebook ids when authentificating, store them in yaml array. (see @ end how can load them database).

here's did:

#/app/config.yml #the setup looks different (i need picture , email credentials) hwi_oauth:   # name of firewall in bundle active, setting must set   firewall_name: secured_area   resource_owners:     facebook:       type:        facebook       client_id:       %facebook_client_id%       client_secret:     %facebook_client_secret%       scope:         "email"       infos_url:     "https://graph.facebook.com/me?fields=username,name,email,picture.type(square)"       paths:         email:          email         profilepicture: picture.data.url services: #here's magic happens   hwi_oauth.user.provider.entity:     class: hwi\bundle\oauthbundle\security\core\user\oauthuserprovider   ib_user.oauth_user_provider:     class: acme\demobundle\provider\provider     arguments: [@session, @doctrine, %admins%]  #app/security.yml security:   providers:     my_custom_hwi_provider:       id: ib_user.oauth_user_provider    access_control:         - { path: ^/admin, roles: role_super_admin }    #app/parameters.yml parameters:   #...   facebook_client_id:     ###   facebook_client_secret: ###   admins:     - "my.facebook.id"  #acme\demobundle\provider\provider <?php  namespace acme\demobundle\provider;  use hwi\bundle\oauthbundle\security\core\user\oauthuserprovider; use hwi\bundle\oauthbundle\oauth\response\userresponseinterface; use acme\demobundle\entity\user; use acme\demobundle\provider\oauthuser;  class provider extends oauthuserprovider {     protected $session, $doctrine, $admins;     public function __construct($session, $doctrine, $admins) {         $this->session = $session;         $this->doctrine = $doctrine;         $this->admins = $admins;     }      public function loaduserbyusername($username)     {         return new oauthuser($username, $this->isuseradmin($username)); //look @ class below     }      private function isuseradmin($nickname)     {         return in_array($nickname, $this->admins);     }      public function loaduserbyoauthuserresponse(userresponseinterface $response)     {         //data facebook response         $facebook_id = $response->getusername();         $nickname = $response->getnickname();         $realname = $response->getrealname();         $email    = $response->getemail();         $avatar   = $response->getprofilepicture();          //set data in session         $this->session->set('nickname', $nickname);         $this->session->set('realname', $realname);         $this->session->set('email', $email);         $this->session->set('avatar', $avatar);          //get user fid         $qb = $this->doctrine->getmanager()->createquerybuilder();         $qb ->select('u.id')             ->from('acmedemobundle:user', 'u')             ->where('u.fid = :fid')             ->setparameter('fid', $facebook_id)             ->setmaxresults(1);         $result = $qb->getquery()->getresult();          //add database if doesn't exists         if ( !count($result) ) {             $user = new user();             $user->setcreatedat(new \datetime());             $user->setnickname($nickname);             $user->setrealname($realname);             $user->setemail($email);             $user->setavatar($avatar);             $user->setfid($facebook_id);              $em = $this->doctrine->getmanager();             $em->persist($user);             $id = $em->flush();         } else {             $id = $result[0]['id'];         }          //set id         $this->session->set('id', $id);          //@todo: hmm : admin         if ($this->isuseradmin($nickname)) {             $this->session->set('is_admin', true);         }          //parent:: returned value         return $this->loaduserbyusername($response->getnickname());     }      public function supportsclass($class)     {         return $class === 'acme\\demobundle\\provider\\oauthuser';     } }   #acme\demobundle\provider\oauthuser <?php  namespace acme\demobundle\provider;  use hwi\bundle\oauthbundle\security\core\user\oauthuser hwioauthuser;  class oauthuser extends hwioauthuser{     private $isadmin = false;     public function __construct($username, $isadmin = false)     {         parent::__construct($username);         $this->isadmin = $isadmin;     }      public function getroles()     {         $roles = array('role_user', 'role_oauth_user');          if ($this->isadmin) {             array_push($roles, 'role_super_admin');         }          return $roles;     } } 

so can pretty see when facebook login response comes, database checks (based on facebook graph id), , add if needed. also, set things in sessions (you won't need this), , after must return hwi\bundle\oauthbundle\security\core\user\oauthuser object (this sf2 gets it's roles). extend (in way have acces $isadmin). said, need roles each user , must edit them. that, can implement getroles() manytomany relationship (give access doctrine entitymanager via constructor). can see applied here: http://symfony.com/doc/current/cookbook/security/entity_provider.html#managing-roles-in-the-database .

as said, must tweak lot (my app facebook-only login , in_memory security access), wish myself had code when started. hope hels you. post questions, if any.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -