SlideShare a Scribd company logo
novactive. Paris Toulon San FranciscoMontréalTunis
How to integrate FOSUserBundle in eZ Platform
to externalize Users in MongoDB
https://github.com/Novactive/NovaeZFOSUserBundle
novactive. Paris Toulon San FranciscoMontréalTunis
Novactive

Premier Sponsor
novactive. Paris Toulon San FranciscoMontréalTunis
Novactive Group
๏ Novactive France
๏ Paris ~ 19 years old

๏ Toulon ~ 2 years old

๏ Novactive Tunis ~ 8 years old

๏ Novactive Canada Inc. 

๏ Montréal ~ 4 years

๏ Novactive Corporation 

๏ San Francisco ~ 1 year old
Worldwide Team 80 employees
๏ Digital Consulting

๏ Web Development

๏ e-Commerce

๏ Web Marketing

๏ Mobile Apps
novactive. Paris Toulon San FranciscoMontréalTunis
Novactive and eZ Systems
๏ Over 10 years of partnership

๏ First eZ project developed in 2005

๏ 70% of our projects are eZ Publish based technology

๏ Over 150 projects delivered with eZ Publish

๏ More than 40 websites currently in ongoing maintenance
on eZ Publish

๏ Provider of professional extensions for the eZ Market
novactive. Paris Toulon San FranciscoMontréalTunis
Let’s get started!
novactive. Paris Toulon San FranciscoMontréalTunis
User management in eZ
➡ Simple

➡ Extensible

➡ Robust

➡ Extremely powerful roles and
policies system

➡ Almost no limit

➡ Managed like Contents
novactive. Paris Toulon San FranciscoMontréalTunis
User Group 1 Role 1
User A
User B
User Group 2
User C
User D
User B
Policy 10
Policy 11
Policy 12
Policy 13
Role 2
Policy 20
Policy 21
novactive. Paris Toulon San FranciscoMontréalTunis
User B
Policy 10
Policy 11
Policy 12
Policy 13
Policy 20
Policy 21
Role 1
Role 2
novactive. Paris Toulon San FranciscoMontréalTunis
A User is not a Content
๏ Performance issue

๏ Dependency between

๏ User repository

๏ Content repository

๏ Hard to manage a website with

๏ 300 000 articles

๏ 7 millions Subscribers/Members
novactive. Paris Toulon San FranciscoMontréalTunis
Users externalization
A good approach
keeping the policy system
novactive. Paris Toulon San FranciscoMontréalTunis
A good approach
➡ Keeping only one UserAccount Field Type in eZ

➡ And “join” on an email or on an id
➡ Pros
➡ All the built-in features of eZ stay functional
➡ Cons
➡ Need to extend the Administration Interface 

➡ Still using the famous ezcontentobject_attribute table
novactive. Paris Toulon San FranciscoMontréalTunis
Do we have a better
approach with 

eZ Platform?
novactive. Paris Toulon San FranciscoMontréalTunis
– The Amazing eZ Documentation
“Symfony provides native support for multiple
user providers. This makes it easy to integrate
any kind of login handlers, including SSO and
existing 3rd party bundles”
novactive. Paris Toulon San FranciscoMontréalTunis
Thanks eZ Platform
Thanks Symfony and the community !
novactive. Paris Toulon San FranciscoMontréalTunis
FOS User Bundle

Friends Of Symfony User Bundle
novactive. Paris Toulon San FranciscoMontréalTunis
FOS User Bundle
๏ The best and most useful Symfony2 bundle

๏ More than 3.1 million installations
๏ Ready and simple to use

๏ Reliable and unit tested

๏ Documentation on symfony.com
http://symfony.com/blog/the-30-most-useful-symfony-bundles-and-making-them-even-better
https://packagist.org/packages/friendsofsymfony/user-bundle
novactive. Paris Toulon San FranciscoMontréalTunis
FOS User Bundle
✓ Registration, with an optional email confirmation

✓ Password reset

✓ Profile edition over the Symfony Forms

✓ Group of users

✓ Invitations are coming

✓ Custom storage layer
novactive. Paris Toulon San FranciscoMontréalTunis
MongoDB
ready
✓ Through Doctrine ODM

✓ CouchDB support available
novactive. Paris Toulon San FranciscoMontréalTunis
eZ
+ 

Symfony 

+

External User provider
https://doc.ez.no/display/EZP/How+to+authenticate+a+user+with+multiple+user+providers
We have
Everything we need!
novactive. Paris Toulon San FranciscoMontréalTunis
Some inputs
๏ API User
๏ Stored into the eZ database

๏ Contains the UserAccount Fields

๏ Is connected to the Role and Permissions

๏ UserWrapped
๏ A combination of

๏ 1 API User

๏ 1 External User (also called the WrappedUser)
novactive. Paris Toulon San FranciscoMontréalTunis
For Instance
UserWrapped
API User
In eZ
WrappedUser
In Mongo DB
linked to the
Policies
novactive. Paris Toulon San FranciscoMontréalTunis
UserWrapped
API User + Matched User
eZ
A user is
matched
get eZ API
User
Native
Interactive
Login
Listener
SecurityEvents

INTERACTIVE_LOGIN
eZ
Interactive
Login
Listener
Token
User
Simplified process
login
MVCEvents

INTERACTIVE_LOGIN
novactive. Paris Toulon San FranciscoMontréalTunis
User Group 1 Role 1
User Type 1
User Group 2
User E
User I
User A
Role 2
User Type 2
E
Z
D
B
M

O

N

G

O
D
B
User F
User J
User B
User G
User K
User C
User H
User L
User D
User M User N User N+1 User N+2
novactive. Paris Toulon San FranciscoMontréalTunis
Let’s do it
novactive. Paris Toulon San FranciscoMontréalTunis
Assumptions
✓ An eZ Platform installation working

✓ Composer installed

✓ A MongoDB instance working
novactive. Paris Toulon San FranciscoMontréalTunis
Installation
$ php composer.phar require doctrine/mongodb-odm-bundle:'3.0.*@dev'
$ php composer.phar require friendsofsymfony/user-bundle:~2.0@dev
// ezpublish/EzPublishKernel.php
public function registerBundles()

{

$bundles = array(

…
new FOSUserBundleFOSUserBundle(),

new DoctrineBundleMongoDBBundle
DoctrineMongoDBBundle(),
);
}
novactive. Paris Toulon San FranciscoMontréalTunis
FOS Configuration
# ezpublish/config/config.yml
fos_user:

db_driver: mongodb

firewall_name: ezpublish_front

user_class: NovactiveBundleeZFOSUserBundle
DocumentUser
# app/config/routing.yml

fos_user:

resource: "@FOSUserBundle/Resources/config/
routing/all.xml"
novactive. Paris Toulon San FranciscoMontréalTunis
Extend FOS Bundle
class NovaeZFOSUserBundle extends Bundle

{

/**

* Extends FOS

*

* @return string

*/

public function getParent()

{

return 'FOSUserBundle';

}

}
novactive. Paris Toulon San FranciscoMontréalTunis
ODM Configuration
# ezpublish/config/config.yml
doctrine_mongodb:

connections:

default:

server: 'mongodb://localhost:27017'

options: {}

default_database: 'EZCONFNYC2015'

document_managers:

default:

auto_mapping: true
novactive. Paris Toulon San FranciscoMontréalTunis
User Document
namespace NovactiveBundleeZFOSUserBundleDocument;



use FOSUserBundleModelUser as BaseUser;

use DoctrineODMMongoDBMappingAnnotations as MongoDB;


/**

* Class User

* @MongoDBDocument

*/
class User extends BaseUser

{

/**

* Identifier

*

* @var int Identifier

*

* @MongoDBId(strategy="auto")

*/

protected $id;



/**

* @var bool

*

* @MongoDBBoolean

*/

protected $isCertified;



/**

* @var array

*

* @MongoDBCollection

*/

protected $certifiedDates;
……

novactive. Paris Toulon San FranciscoMontréalTunis
User Document
php ezpublish/console doctrine:mongodb:schema:create --index
RoboMongo
novactive. Paris Toulon San FranciscoMontréalTunis
Security Configuration
security:



encoders:

FOSUserBundleModelUserInterface: bcrypt



role_hierarchy:

ROLE_ADMIN: ROLE_USER

ROLE_SUPER_ADMIN: ROLE_ADMIN



providers:

chain_provider:

chain:

providers: [novaezfos_provider, ezpublish]

novaezfos_provider:

id: fos_user.user_provider.username

ezpublish:

id: ezpublish.security.user_provider
novactive. Paris Toulon San FranciscoMontréalTunis
UserWrapped
API User + Matched User
eZ
A user is
matched
get eZ API
User
Native
Interactive
Login
Listener
SecurityEvents

INTERACTIVE_LOGIN
eZ
Interactive
Login
Listener
Token
User
Simplified process
login
MVCEvents

INTERACTIVE_LOGIN
novactive. Paris Toulon San FranciscoMontréalTunis
Mapping the API User
✓ Listen the MVCEvents::INTERACTIVE_LOGIN
services:



novactive.ezfosuser.interactive_event_listener:

class: NovactiveBundleeZFOSUserBundleListener
InteractiveLoginListener

arguments: [@ezpublish.api.service.user]

tags:

- { name: kernel.event_subscriber }
novactive. Paris Toulon San FranciscoMontréalTunis
Set the API User


class InteractiveLoginListener implements EventSubscriberInterface

{

……

public function onInteractiveLogin(InteractiveLoginEvent $event)

{

// We just load a generic user and assign it back to the event.

// You may want to create users here, or even load predefined users depending on
your own rules.


$event->setApiUser(
$this->userService->loadUserByLogin(‘UserType1’)
);


}

}

novactive. Paris Toulon San FranciscoMontréalTunis
UserWrapped
API User + Matched User
eZ
A user is
matched
get eZ API
User
Native
Interactive
Login
Listener
SecurityEvents

INTERACTIVE_LOGIN
eZ
Interactive
Login
Listener
Token
User
Simplified process
login
MVCEvents

INTERACTIVE_LOGIN
novactive. Paris Toulon San FranciscoMontréalTunis
Layout
novactive. Paris Toulon San FranciscoMontréalTunis
Layout
๏ Thanks to the FOS Bundle overriding
{# eZFOSUserBundle/Resources/views/layout.html.twig #}
{% extends "eZDemoBundle::pagelayout.html.twig" %}


{% block content %}

<div>

{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}

{{ 'layout.logged_in_as'|trans({'%username%': app.user.username},
'FOSUserBundle') }} |

<a href="{{ path('fos_user_security_logout') }}">

{{ 'layout.logout'|trans({}, 'FOSUserBundle') }}

</a>

{% else %}

<a href="{{ path('fos_user_security_login') }}">{{ 'layout.login'|
trans({}, 'FOSUserBundle') }}</a>

{% endif %}

</div>

{% if app.request.hasPreviousSession %}

novactive. Paris Toulon San FranciscoMontréalTunis
eZ Layout
novactive. Paris Toulon San FranciscoMontréalTunis
Recap
✓ Our MongoDB database ready

✓ FOS configured

✓ You can log in with an API User 

✓ You will get a API User authenticated

✓ You can log in with a FOS User

✓ You will get a User Wrapped authenticated
novactive. Paris Toulon San FranciscoMontréalTunis
Are we done?
novactive. Paris Toulon San FranciscoMontréalTunis
Why ?
๏ FOS User Bundle doesn’t know what a
UserWrapped is

๏ You need to be compliant to its Interface:

๏ FOSUserBundleModelUserInterface

๏ 
// FOS Controller action - first lines
$user = $this->getUser();

if (!is_object($user) || !$user instanceof UserInterface) {

throw new AccessDeniedException('This user does not have
access to this section.');

novactive. Paris Toulon San FranciscoMontréalTunis
Basic install
Implement the FOS Interface
Create the DataViewTransformer
Refresh the FOS User
Create the ImplicitLoginListener
Extend the FOS User manager
novactive. Paris Toulon San FranciscoMontréalTunis
–The Amazing eZ Documentation
“It is possible to customize the user class used
by extending ezpublish.security.login_listener
service,[…] and override getUser() to return
whatever user class you want.”
novactive. Paris Toulon San FranciscoMontréalTunis
Wrapped User
✓ You need to be compliant to:

✓ FOSUserBundleModelUserInterface
✓ Override
parameters:

ezpublish.security.login_listener.class: TheEconomist
BundleUserBundleEventListenerSecurityListener

class SecurityListener extends BaseSecurityListener {

protected function getUser(UserInterface $originalUser,
APIUser $apiUser) {

return new UserWrapped($originalUser, $apiUser);

}

}
novactive. Paris Toulon San FranciscoMontréalTunis
–Our next error
“The form's view data is expected to be an
instance of class DocumentUser, but is an
instance of class CoreUserWrapped.”
novactive. Paris Toulon San FranciscoMontréalTunis
Data Transformer


public function transform($value)

{

if ($value instanceof UserWrapped) {

return $value->getWrappedUser();

}



return $value;

}



public function reverseTransform($value)

{

return $value;

}
✓ To use this transformer you need to add it to the form type

✓ Extend the Form Type
novactive. Paris Toulon San FranciscoMontréalTunis
Create the profile Form Type
novactive.ezfosuser.novactive_ezfosuser_profile.form.type:

class: NovactiveBundleeZFOSUserBundleFormTypeProfile

tags:

- { name: form.type, alias:
novactive_ezfosuser_profile}
use SymfonyComponentFormAbstractType;

class Profile extends AbstractType {



public function buildForm(FormBuilderInterface $builder, array $options) {

$builder->add('firstname')->add('lastname')->add('isCertified');

$builder->addViewTransformer( new UserWrappedToUser());

}



public function getParent() {

return 'fos_user_profile';

}



public function getName() {

return 'novactive_ezfosuser_profile';

}

}
novactive. Paris Toulon San FranciscoMontréalTunis
–in vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/
MappingException.php at line 37
“The class 'NovactiveBundle
eZFOSUserBundleCoreUserWrapped' was
not found in the chain configured
namespaces NovactiveBundle
eZFOSUserBundleDocument, FOS
UserBundleModel ”
novactive. Paris Toulon San FranciscoMontréalTunis
Extend the User manager
novactive.ezfosuser.fos_user_manager:

class: NovactiveBundleeZFOSUserBundleDoctrine
UserManager

parent: fos_user.user_manager.default
public function __method__User(UserInterface $user, $andFlush = true)

{

if ($user instanceof UserWrapped) {

parent::__method__User($user->getWrappedUser(), $andFlush);



return;

}

parent::__method__User($user, $andFlush);

}
novactive. Paris Toulon San FranciscoMontréalTunis
Basic install
Implement the FOS Interface
Create the DataViewTransformer
Refresh the FOS User
Create the ImplicitLoginListener
Extend the FOS User manager
novactive. Paris Toulon San FranciscoMontréalTunis
Refresh user
novactive.ezfosuser.user_provider.username_email:

class: NovactiveBundleeZFOSUserBundleSecurity
UserProvider

arguments: [ @fos_user.user_manager ]
providers:

chain_provider:

chain:

providers: [novaezfos_provider, ezpublish]

novaezfos_provider:

id: fos_user.user_provider.username
id: novactive.ezfosuser.user_provider.username_email

ezpublish:

id: ezpublish.security.user_provider
novactive. Paris Toulon San FranciscoMontréalTunis
Refresh user
class UserProvider extends EmailUserProvider {



public function refreshUser(SecurityUserInterface $user)

{

if (!$user instanceof UserWrapped) {

throw new UnsupportedUserException(…);

}

if (null ===

$reloadedUser = $this->userManager->findUserBy(array( 'id' => $user-
>getWrappedUser()->getId() ))

) {

throw new UsernameNotFoundException(…;

}

$user->setWrappedUser($reloadedUser);

throw new UnsupportedUserException("Forward to the
ezpublish provider");

}



}
novactive. Paris Toulon San FranciscoMontréalTunis
Final step
novactive. Paris Toulon San FranciscoMontréalTunis
Basic install
Implement the FOS Interface
Create the DataViewTransformer
Create the ImplicitLoginListener
Extend the FOS User manager
Refresh the FOS User
novactive. Paris Toulon San FranciscoMontréalTunis
Implicit Login
๏ Goal

๏ Rely on the eZ Interactive Login
๏ Steps

1 - Dispatch the event.

2 - If no eZ user is returned, load Anonymous user.

3 - Inject eZ user in repository.

4 - Create the UserWrapped user object 

5 - Create new token with UserWrapped user

6 - Inject the new token in security context
novactive. Paris Toulon San FranciscoMontréalTunis
Implicit Login
novactive.ezfosuser.implicit_event_listener:

class: NovactiveBundleeZFOSUserBundleListener
ImplicitLoginListener

arguments:

- @ezpublish.api.repository

- @ezpublish.config.resolver

- @event_dispatcher

- @security.token_storage

tags:

- { name: kernel.event_subscriber }
novactive. Paris Toulon San FranciscoMontréalTunis
$originalUser = $event->getUser();

if ($originalUser instanceof eZUser || !$originalUser instanceof UserInterface) {

return;

}



$token = $this->tokenStorage->getToken();



$subLoginEvent = new InteractiveLoginEvent($event->getRequest(), $token);

$this->eventDispatcher->dispatch(MVCEvents::INTERACTIVE_LOGIN, $subLoginEvent);

if ($subLoginEvent->hasAPIUser()) {

$apiUser = $subLoginEvent->getAPIUser();

}

else {

$apiUser = $this->repository->getUserService()->loadUser(

$this->configResolver->getParameter('anonymous_user_id')

);

}

$this->repository->setCurrentUser($apiUser);

$providerKey = method_exists($token, 'getProviderKey') ? $token-
>getProviderKey() : __CLASS__;

$interactiveToken = new InteractiveLoginToken(

new UserWrapped($originalUser, $apiUser),

get_class($token),

$token->getCredentials(),

$providerKey,

$token->getRoles()

);

$interactiveToken->setAttributes($token->getAttributes());

$this->tokenStorage->setToken($interactiveToken);
novactive. Paris Toulon San FranciscoMontréalTunis
You did it
Congratulations
novactive. Paris Toulon San FranciscoMontréalTunis
Wanna
Go further?
Install HWI OAuth for

Social Connectors !
novactive. Paris Toulon San FranciscoMontréalTunis
Thank you!
https://twitter.com/NovactiveSF

https://twitter.com/Plopix
https://www.facebook.com/NovactiveSF
http://www.novactive.us
s.morel@novactive.us
https://github.com/Novactive/NovaeZFOSUserBundle

More Related Content

Similar to FOSUserBundle with eZ Platform and MongoDB

What's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon TalkWhat's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon Talk
Sam Basu
 
Alex Terente - Introduction to iOS
Alex Terente - Introduction to iOSAlex Terente - Introduction to iOS
Alex Terente - Introduction to iOS
Codecamp Romania
 
Azure + WP7 - CodePaLOUsa
Azure + WP7 - CodePaLOUsaAzure + WP7 - CodePaLOUsa
Azure + WP7 - CodePaLOUsa
Sam Basu
 
BarCamp KL H20 Open Social Hackathon
BarCamp KL H20 Open Social HackathonBarCamp KL H20 Open Social Hackathon
BarCamp KL H20 Open Social Hackathon
marvin337
 

Similar to FOSUserBundle with eZ Platform and MongoDB (20)

What's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon TalkWhat's New with Windows Phone - FoxCon Talk
What's New with Windows Phone - FoxCon Talk
 
Alex Terente - Introduction to iOS
Alex Terente - Introduction to iOSAlex Terente - Introduction to iOS
Alex Terente - Introduction to iOS
 
Azure + WP7 - CodePaLOUsa
Azure + WP7 - CodePaLOUsaAzure + WP7 - CodePaLOUsa
Azure + WP7 - CodePaLOUsa
 
Goodle Developer Days London 2008 - Open Social Update
Goodle Developer Days London 2008 - Open Social UpdateGoodle Developer Days London 2008 - Open Social Update
Goodle Developer Days London 2008 - Open Social Update
 
Blug2012 yellow and blue stream
Blug2012 yellow and blue streamBlug2012 yellow and blue stream
Blug2012 yellow and blue stream
 
Intro to Muon - How to build Polyglot Message and Event Microservices
Intro to Muon - How to build Polyglot Message and Event MicroservicesIntro to Muon - How to build Polyglot Message and Event Microservices
Intro to Muon - How to build Polyglot Message and Event Microservices
 
Meetic Mobile Strategy - Microsoft TechDays Paris 2015
Meetic Mobile Strategy - Microsoft TechDays Paris 2015Meetic Mobile Strategy - Microsoft TechDays Paris 2015
Meetic Mobile Strategy - Microsoft TechDays Paris 2015
 
Stratégie mobile de Meetic sur Windows
Stratégie mobile de Meetic sur WindowsStratégie mobile de Meetic sur Windows
Stratégie mobile de Meetic sur Windows
 
Easy Step-by-Step Guide to Develop REST APIs with Django REST Framework
Easy Step-by-Step Guide to Develop REST APIs with Django REST FrameworkEasy Step-by-Step Guide to Develop REST APIs with Django REST Framework
Easy Step-by-Step Guide to Develop REST APIs with Django REST Framework
 
OAuth for QuickBooks Online REST Services
OAuth for QuickBooks Online REST ServicesOAuth for QuickBooks Online REST Services
OAuth for QuickBooks Online REST Services
 
Pune_Einstein Chatbot integration using Mulesoft.pdf
Pune_Einstein Chatbot integration using Mulesoft.pdfPune_Einstein Chatbot integration using Mulesoft.pdf
Pune_Einstein Chatbot integration using Mulesoft.pdf
 
Building Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in RailsBuilding Mobile Friendly APIs in Rails
Building Mobile Friendly APIs in Rails
 
Goodle Developer Days Munich 2008 - Open Social Update
Goodle Developer Days Munich 2008 - Open Social UpdateGoodle Developer Days Munich 2008 - Open Social Update
Goodle Developer Days Munich 2008 - Open Social Update
 
DDive11 - Mobile Development For Domino
DDive11 - Mobile Development For DominoDDive11 - Mobile Development For Domino
DDive11 - Mobile Development For Domino
 
BarCamp KL H20 Open Social Hackathon
BarCamp KL H20 Open Social HackathonBarCamp KL H20 Open Social Hackathon
BarCamp KL H20 Open Social Hackathon
 
Project Flogo: An Event-Driven Stack for the Enterprise
Project Flogo: An Event-Driven Stack for the EnterpriseProject Flogo: An Event-Driven Stack for the Enterprise
Project Flogo: An Event-Driven Stack for the Enterprise
 
Open stack gbp final sn-4-slideshare
Open stack gbp final sn-4-slideshareOpen stack gbp final sn-4-slideshare
Open stack gbp final sn-4-slideshare
 
Vitaliy Makogon: Migration to ivy. Angular component libraries with IVY support.
Vitaliy Makogon: Migration to ivy. Angular component libraries with IVY support.Vitaliy Makogon: Migration to ivy. Angular component libraries with IVY support.
Vitaliy Makogon: Migration to ivy. Angular component libraries with IVY support.
 
Opensocial
OpensocialOpensocial
Opensocial
 
ONLINE FOOD ORDERS THROUGH WHATSAPP AUTOMATION BOT
ONLINE FOOD ORDERS THROUGH WHATSAPP AUTOMATION BOTONLINE FOOD ORDERS THROUGH WHATSAPP AUTOMATION BOT
ONLINE FOOD ORDERS THROUGH WHATSAPP AUTOMATION BOT
 

Recently uploaded

Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
mbmh111980
 

Recently uploaded (20)

Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024Top Mobile App Development Companies 2024
Top Mobile App Development Companies 2024
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
AI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning FrameworkAI/ML Infra Meetup | Perspective on Deep Learning Framework
AI/ML Infra Meetup | Perspective on Deep Learning Framework
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
SOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBrokerSOCRadar Research Team: Latest Activities of IntelBroker
SOCRadar Research Team: Latest Activities of IntelBroker
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdf
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.ILBeyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
Beyond Event Sourcing - Embracing CRUD for Wix Platform - Java.IL
 
Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 

FOSUserBundle with eZ Platform and MongoDB

  • 1. novactive. Paris Toulon San FranciscoMontréalTunis How to integrate FOSUserBundle in eZ Platform to externalize Users in MongoDB https://github.com/Novactive/NovaeZFOSUserBundle
  • 2. novactive. Paris Toulon San FranciscoMontréalTunis Novactive Premier Sponsor
  • 3. novactive. Paris Toulon San FranciscoMontréalTunis Novactive Group ๏ Novactive France ๏ Paris ~ 19 years old ๏ Toulon ~ 2 years old ๏ Novactive Tunis ~ 8 years old ๏ Novactive Canada Inc. ๏ Montréal ~ 4 years ๏ Novactive Corporation ๏ San Francisco ~ 1 year old Worldwide Team 80 employees ๏ Digital Consulting ๏ Web Development ๏ e-Commerce ๏ Web Marketing ๏ Mobile Apps
  • 4. novactive. Paris Toulon San FranciscoMontréalTunis Novactive and eZ Systems ๏ Over 10 years of partnership ๏ First eZ project developed in 2005 ๏ 70% of our projects are eZ Publish based technology ๏ Over 150 projects delivered with eZ Publish ๏ More than 40 websites currently in ongoing maintenance on eZ Publish ๏ Provider of professional extensions for the eZ Market
  • 5. novactive. Paris Toulon San FranciscoMontréalTunis Let’s get started!
  • 6. novactive. Paris Toulon San FranciscoMontréalTunis User management in eZ ➡ Simple ➡ Extensible ➡ Robust ➡ Extremely powerful roles and policies system ➡ Almost no limit ➡ Managed like Contents
  • 7. novactive. Paris Toulon San FranciscoMontréalTunis User Group 1 Role 1 User A User B User Group 2 User C User D User B Policy 10 Policy 11 Policy 12 Policy 13 Role 2 Policy 20 Policy 21
  • 8. novactive. Paris Toulon San FranciscoMontréalTunis User B Policy 10 Policy 11 Policy 12 Policy 13 Policy 20 Policy 21 Role 1 Role 2
  • 9. novactive. Paris Toulon San FranciscoMontréalTunis A User is not a Content ๏ Performance issue ๏ Dependency between ๏ User repository ๏ Content repository ๏ Hard to manage a website with ๏ 300 000 articles ๏ 7 millions Subscribers/Members
  • 10. novactive. Paris Toulon San FranciscoMontréalTunis Users externalization A good approach keeping the policy system
  • 11. novactive. Paris Toulon San FranciscoMontréalTunis A good approach ➡ Keeping only one UserAccount Field Type in eZ ➡ And “join” on an email or on an id ➡ Pros ➡ All the built-in features of eZ stay functional ➡ Cons ➡ Need to extend the Administration Interface ➡ Still using the famous ezcontentobject_attribute table
  • 12. novactive. Paris Toulon San FranciscoMontréalTunis Do we have a better approach with eZ Platform?
  • 13. novactive. Paris Toulon San FranciscoMontréalTunis – The Amazing eZ Documentation “Symfony provides native support for multiple user providers. This makes it easy to integrate any kind of login handlers, including SSO and existing 3rd party bundles”
  • 14. novactive. Paris Toulon San FranciscoMontréalTunis Thanks eZ Platform Thanks Symfony and the community !
  • 15. novactive. Paris Toulon San FranciscoMontréalTunis FOS User Bundle Friends Of Symfony User Bundle
  • 16. novactive. Paris Toulon San FranciscoMontréalTunis FOS User Bundle ๏ The best and most useful Symfony2 bundle ๏ More than 3.1 million installations ๏ Ready and simple to use ๏ Reliable and unit tested ๏ Documentation on symfony.com http://symfony.com/blog/the-30-most-useful-symfony-bundles-and-making-them-even-better https://packagist.org/packages/friendsofsymfony/user-bundle
  • 17. novactive. Paris Toulon San FranciscoMontréalTunis FOS User Bundle ✓ Registration, with an optional email confirmation ✓ Password reset ✓ Profile edition over the Symfony Forms ✓ Group of users ✓ Invitations are coming ✓ Custom storage layer
  • 18. novactive. Paris Toulon San FranciscoMontréalTunis MongoDB ready ✓ Through Doctrine ODM ✓ CouchDB support available
  • 19. novactive. Paris Toulon San FranciscoMontréalTunis eZ + Symfony + External User provider https://doc.ez.no/display/EZP/How+to+authenticate+a+user+with+multiple+user+providers We have Everything we need!
  • 20. novactive. Paris Toulon San FranciscoMontréalTunis Some inputs ๏ API User ๏ Stored into the eZ database ๏ Contains the UserAccount Fields ๏ Is connected to the Role and Permissions ๏ UserWrapped ๏ A combination of ๏ 1 API User ๏ 1 External User (also called the WrappedUser)
  • 21. novactive. Paris Toulon San FranciscoMontréalTunis For Instance UserWrapped API User In eZ WrappedUser In Mongo DB linked to the Policies
  • 22. novactive. Paris Toulon San FranciscoMontréalTunis UserWrapped API User + Matched User eZ A user is matched get eZ API User Native Interactive Login Listener SecurityEvents
 INTERACTIVE_LOGIN eZ Interactive Login Listener Token User Simplified process login MVCEvents
 INTERACTIVE_LOGIN
  • 23. novactive. Paris Toulon San FranciscoMontréalTunis User Group 1 Role 1 User Type 1 User Group 2 User E User I User A Role 2 User Type 2 E Z D B M
 O
 N
 G
 O D B User F User J User B User G User K User C User H User L User D User M User N User N+1 User N+2
  • 24. novactive. Paris Toulon San FranciscoMontréalTunis Let’s do it
  • 25. novactive. Paris Toulon San FranciscoMontréalTunis Assumptions ✓ An eZ Platform installation working ✓ Composer installed ✓ A MongoDB instance working
  • 26. novactive. Paris Toulon San FranciscoMontréalTunis Installation $ php composer.phar require doctrine/mongodb-odm-bundle:'3.0.*@dev' $ php composer.phar require friendsofsymfony/user-bundle:~2.0@dev // ezpublish/EzPublishKernel.php public function registerBundles()
 {
 $bundles = array(
 … new FOSUserBundleFOSUserBundle(),
 new DoctrineBundleMongoDBBundle DoctrineMongoDBBundle(), ); }
  • 27. novactive. Paris Toulon San FranciscoMontréalTunis FOS Configuration # ezpublish/config/config.yml fos_user:
 db_driver: mongodb
 firewall_name: ezpublish_front
 user_class: NovactiveBundleeZFOSUserBundle DocumentUser # app/config/routing.yml
 fos_user:
 resource: "@FOSUserBundle/Resources/config/ routing/all.xml"
  • 28. novactive. Paris Toulon San FranciscoMontréalTunis Extend FOS Bundle class NovaeZFOSUserBundle extends Bundle
 {
 /**
 * Extends FOS
 *
 * @return string
 */
 public function getParent()
 {
 return 'FOSUserBundle';
 }
 }
  • 29. novactive. Paris Toulon San FranciscoMontréalTunis ODM Configuration # ezpublish/config/config.yml doctrine_mongodb:
 connections:
 default:
 server: 'mongodb://localhost:27017'
 options: {}
 default_database: 'EZCONFNYC2015'
 document_managers:
 default:
 auto_mapping: true
  • 30. novactive. Paris Toulon San FranciscoMontréalTunis User Document namespace NovactiveBundleeZFOSUserBundleDocument;
 
 use FOSUserBundleModelUser as BaseUser;
 use DoctrineODMMongoDBMappingAnnotations as MongoDB; 
 /**
 * Class User
 * @MongoDBDocument
 */ class User extends BaseUser
 {
 /**
 * Identifier
 *
 * @var int Identifier
 *
 * @MongoDBId(strategy="auto")
 */
 protected $id;
 
 /**
 * @var bool
 *
 * @MongoDBBoolean
 */
 protected $isCertified;
 
 /**
 * @var array
 *
 * @MongoDBCollection
 */
 protected $certifiedDates; ……

  • 31. novactive. Paris Toulon San FranciscoMontréalTunis User Document php ezpublish/console doctrine:mongodb:schema:create --index RoboMongo
  • 32. novactive. Paris Toulon San FranciscoMontréalTunis Security Configuration security:
 
 encoders:
 FOSUserBundleModelUserInterface: bcrypt
 
 role_hierarchy:
 ROLE_ADMIN: ROLE_USER
 ROLE_SUPER_ADMIN: ROLE_ADMIN
 
 providers:
 chain_provider:
 chain:
 providers: [novaezfos_provider, ezpublish]
 novaezfos_provider:
 id: fos_user.user_provider.username
 ezpublish:
 id: ezpublish.security.user_provider
  • 33. novactive. Paris Toulon San FranciscoMontréalTunis UserWrapped API User + Matched User eZ A user is matched get eZ API User Native Interactive Login Listener SecurityEvents
 INTERACTIVE_LOGIN eZ Interactive Login Listener Token User Simplified process login MVCEvents
 INTERACTIVE_LOGIN
  • 34. novactive. Paris Toulon San FranciscoMontréalTunis Mapping the API User ✓ Listen the MVCEvents::INTERACTIVE_LOGIN services:
 
 novactive.ezfosuser.interactive_event_listener:
 class: NovactiveBundleeZFOSUserBundleListener InteractiveLoginListener
 arguments: [@ezpublish.api.service.user]
 tags:
 - { name: kernel.event_subscriber }
  • 35. novactive. Paris Toulon San FranciscoMontréalTunis Set the API User 
 class InteractiveLoginListener implements EventSubscriberInterface
 {
 ……
 public function onInteractiveLogin(InteractiveLoginEvent $event)
 {
 // We just load a generic user and assign it back to the event.
 // You may want to create users here, or even load predefined users depending on your own rules. 
 $event->setApiUser( $this->userService->loadUserByLogin(‘UserType1’) ); 
 }
 }

  • 36. novactive. Paris Toulon San FranciscoMontréalTunis UserWrapped API User + Matched User eZ A user is matched get eZ API User Native Interactive Login Listener SecurityEvents
 INTERACTIVE_LOGIN eZ Interactive Login Listener Token User Simplified process login MVCEvents
 INTERACTIVE_LOGIN
  • 37. novactive. Paris Toulon San FranciscoMontréalTunis Layout
  • 38. novactive. Paris Toulon San FranciscoMontréalTunis Layout ๏ Thanks to the FOS Bundle overriding {# eZFOSUserBundle/Resources/views/layout.html.twig #} {% extends "eZDemoBundle::pagelayout.html.twig" %} 
 {% block content %}
 <div>
 {% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
 {{ 'layout.logged_in_as'|trans({'%username%': app.user.username}, 'FOSUserBundle') }} |
 <a href="{{ path('fos_user_security_logout') }}">
 {{ 'layout.logout'|trans({}, 'FOSUserBundle') }}
 </a>
 {% else %}
 <a href="{{ path('fos_user_security_login') }}">{{ 'layout.login'| trans({}, 'FOSUserBundle') }}</a>
 {% endif %}
 </div>
 {% if app.request.hasPreviousSession %}

  • 39. novactive. Paris Toulon San FranciscoMontréalTunis eZ Layout
  • 40. novactive. Paris Toulon San FranciscoMontréalTunis Recap ✓ Our MongoDB database ready ✓ FOS configured ✓ You can log in with an API User ✓ You will get a API User authenticated ✓ You can log in with a FOS User ✓ You will get a User Wrapped authenticated
  • 41. novactive. Paris Toulon San FranciscoMontréalTunis Are we done?
  • 42. novactive. Paris Toulon San FranciscoMontréalTunis Why ? ๏ FOS User Bundle doesn’t know what a UserWrapped is ๏ You need to be compliant to its Interface: ๏ FOSUserBundleModelUserInterface ๏ // FOS Controller action - first lines $user = $this->getUser();
 if (!is_object($user) || !$user instanceof UserInterface) {
 throw new AccessDeniedException('This user does not have access to this section.');

  • 43. novactive. Paris Toulon San FranciscoMontréalTunis Basic install Implement the FOS Interface Create the DataViewTransformer Refresh the FOS User Create the ImplicitLoginListener Extend the FOS User manager
  • 44. novactive. Paris Toulon San FranciscoMontréalTunis –The Amazing eZ Documentation “It is possible to customize the user class used by extending ezpublish.security.login_listener service,[…] and override getUser() to return whatever user class you want.”
  • 45. novactive. Paris Toulon San FranciscoMontréalTunis Wrapped User ✓ You need to be compliant to: ✓ FOSUserBundleModelUserInterface ✓ Override parameters:
 ezpublish.security.login_listener.class: TheEconomist BundleUserBundleEventListenerSecurityListener
 class SecurityListener extends BaseSecurityListener {
 protected function getUser(UserInterface $originalUser, APIUser $apiUser) {
 return new UserWrapped($originalUser, $apiUser);
 }
 }
  • 46. novactive. Paris Toulon San FranciscoMontréalTunis –Our next error “The form's view data is expected to be an instance of class DocumentUser, but is an instance of class CoreUserWrapped.”
  • 47. novactive. Paris Toulon San FranciscoMontréalTunis Data Transformer 
 public function transform($value)
 {
 if ($value instanceof UserWrapped) {
 return $value->getWrappedUser();
 }
 
 return $value;
 }
 
 public function reverseTransform($value)
 {
 return $value;
 } ✓ To use this transformer you need to add it to the form type ✓ Extend the Form Type
  • 48. novactive. Paris Toulon San FranciscoMontréalTunis Create the profile Form Type novactive.ezfosuser.novactive_ezfosuser_profile.form.type:
 class: NovactiveBundleeZFOSUserBundleFormTypeProfile
 tags:
 - { name: form.type, alias: novactive_ezfosuser_profile} use SymfonyComponentFormAbstractType;
 class Profile extends AbstractType {
 
 public function buildForm(FormBuilderInterface $builder, array $options) {
 $builder->add('firstname')->add('lastname')->add('isCertified');
 $builder->addViewTransformer( new UserWrappedToUser());
 }
 
 public function getParent() {
 return 'fos_user_profile';
 }
 
 public function getName() {
 return 'novactive_ezfosuser_profile';
 }
 }
  • 49. novactive. Paris Toulon San FranciscoMontréalTunis –in vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/ MappingException.php at line 37 “The class 'NovactiveBundle eZFOSUserBundleCoreUserWrapped' was not found in the chain configured namespaces NovactiveBundle eZFOSUserBundleDocument, FOS UserBundleModel ”
  • 50. novactive. Paris Toulon San FranciscoMontréalTunis Extend the User manager novactive.ezfosuser.fos_user_manager:
 class: NovactiveBundleeZFOSUserBundleDoctrine UserManager
 parent: fos_user.user_manager.default public function __method__User(UserInterface $user, $andFlush = true)
 {
 if ($user instanceof UserWrapped) {
 parent::__method__User($user->getWrappedUser(), $andFlush);
 
 return;
 }
 parent::__method__User($user, $andFlush);
 }
  • 51. novactive. Paris Toulon San FranciscoMontréalTunis Basic install Implement the FOS Interface Create the DataViewTransformer Refresh the FOS User Create the ImplicitLoginListener Extend the FOS User manager
  • 52. novactive. Paris Toulon San FranciscoMontréalTunis Refresh user novactive.ezfosuser.user_provider.username_email:
 class: NovactiveBundleeZFOSUserBundleSecurity UserProvider
 arguments: [ @fos_user.user_manager ] providers:
 chain_provider:
 chain:
 providers: [novaezfos_provider, ezpublish]
 novaezfos_provider:
 id: fos_user.user_provider.username id: novactive.ezfosuser.user_provider.username_email
 ezpublish:
 id: ezpublish.security.user_provider
  • 53. novactive. Paris Toulon San FranciscoMontréalTunis Refresh user class UserProvider extends EmailUserProvider {
 
 public function refreshUser(SecurityUserInterface $user)
 {
 if (!$user instanceof UserWrapped) {
 throw new UnsupportedUserException(…);
 }
 if (null ===
 $reloadedUser = $this->userManager->findUserBy(array( 'id' => $user- >getWrappedUser()->getId() ))
 ) {
 throw new UsernameNotFoundException(…;
 }
 $user->setWrappedUser($reloadedUser);
 throw new UnsupportedUserException("Forward to the ezpublish provider");
 }
 
 }
  • 54. novactive. Paris Toulon San FranciscoMontréalTunis Final step
  • 55. novactive. Paris Toulon San FranciscoMontréalTunis Basic install Implement the FOS Interface Create the DataViewTransformer Create the ImplicitLoginListener Extend the FOS User manager Refresh the FOS User
  • 56. novactive. Paris Toulon San FranciscoMontréalTunis Implicit Login ๏ Goal ๏ Rely on the eZ Interactive Login ๏ Steps
 1 - Dispatch the event.
 2 - If no eZ user is returned, load Anonymous user.
 3 - Inject eZ user in repository.
 4 - Create the UserWrapped user object 
 5 - Create new token with UserWrapped user
 6 - Inject the new token in security context
  • 57. novactive. Paris Toulon San FranciscoMontréalTunis Implicit Login novactive.ezfosuser.implicit_event_listener:
 class: NovactiveBundleeZFOSUserBundleListener ImplicitLoginListener
 arguments:
 - @ezpublish.api.repository
 - @ezpublish.config.resolver
 - @event_dispatcher
 - @security.token_storage
 tags:
 - { name: kernel.event_subscriber }
  • 58. novactive. Paris Toulon San FranciscoMontréalTunis $originalUser = $event->getUser();
 if ($originalUser instanceof eZUser || !$originalUser instanceof UserInterface) {
 return;
 }
 
 $token = $this->tokenStorage->getToken();
 
 $subLoginEvent = new InteractiveLoginEvent($event->getRequest(), $token);
 $this->eventDispatcher->dispatch(MVCEvents::INTERACTIVE_LOGIN, $subLoginEvent);
 if ($subLoginEvent->hasAPIUser()) {
 $apiUser = $subLoginEvent->getAPIUser();
 }
 else {
 $apiUser = $this->repository->getUserService()->loadUser(
 $this->configResolver->getParameter('anonymous_user_id')
 );
 }
 $this->repository->setCurrentUser($apiUser);
 $providerKey = method_exists($token, 'getProviderKey') ? $token- >getProviderKey() : __CLASS__;
 $interactiveToken = new InteractiveLoginToken(
 new UserWrapped($originalUser, $apiUser),
 get_class($token),
 $token->getCredentials(),
 $providerKey,
 $token->getRoles()
 );
 $interactiveToken->setAttributes($token->getAttributes());
 $this->tokenStorage->setToken($interactiveToken);
  • 59. novactive. Paris Toulon San FranciscoMontréalTunis You did it Congratulations
  • 60. novactive. Paris Toulon San FranciscoMontréalTunis Wanna Go further? Install HWI OAuth for Social Connectors !
  • 61. novactive. Paris Toulon San FranciscoMontréalTunis Thank you! https://twitter.com/NovactiveSF https://twitter.com/Plopix https://www.facebook.com/NovactiveSF http://www.novactive.us s.morel@novactive.us https://github.com/Novactive/NovaeZFOSUserBundle