FOSElasticaBundle disturbs lifecyle events - symfony

I have installed FOSElasticaBundle to handle search and used the following configuration:
fos_elastica:
clients:
default: { host: localhost, port: 9200 }
indexes:
search:
client: default
types:
post:
mappings:
postTitle: ~
postContent: ~
persistence:
driver: orm
model: Shop\Bundle\ManagementBundle\Entity\Post
provider: ~
listener: ~
finder: ~
Search is working fine, but when I try to login a user, he is succesfully logged in but I get a redirection to login_check route with the following error:
ContextErrorException: Catchable Fatal Error: Argument 1 passed to
FOS\ElasticaBundle\Doctrine\Listener::postUpdate() must be an instance
of Doctrine\Common\Persistence\Event\LifecycleEventArgs, instance of
Doctrine\ORM\Event\LifecycleEventArgs given, called in
C:\xampp\htdocs\community\vendor\symfony\symfony\src\Symfony\Bridge\Doctrine\ContainerAwareEventManager.php
on line 63 and defined in
C:\xampp\htdocs\community\vendor\friendsofsymfony\elastica-bundle\Doctrine\Listener.php
line 111
If I am not wrong, the login_check path is updating the record of the user (precisely the last_login_date field in user table) which triggers the postUpdate() lifecycle event. But I can't resolve the issue. Yout help is appreciated.
PS: I am using FOSUserBundle for users storage in database.
Edit: the above issue happens for other entities persistence lifecycle events (preRemove()...) as well.

Related

How to enable cookies in behat to perform a login functional test?

I am trying to test a valid login with a SonataUserBundle login form and in a behat feature, i'd like to check if user is redirected on the login_check but it seems never working due to cookies problem.
My question is simple, how to perform a valid functional test with behat to check if an user is logged to a Symfony2 application?
I have this configuration in my behat.yml file:
default:
formatters:
pretty: true
autoload:
'': %paths.base%/features/bootstrap
suites:
test_suite:
type: symfony_bundle
bundle: MyBundle
contexts:
- Acme\MyBundle\Features\Context\FeatureContext:
session: '#session'
output_path: build/behat/output
screen_shot_path: build/behat/screenshot
mink_javascript_session: selenium2
extensions:
Behat\Symfony2Extension: ~
Behat\MinkExtension:
base_url: http://<internalURL>/web/app_test.php
sessions:
goutte: # fast, CLI, browser, no javascript support
goutte: ~
selenium2: # fast, CLI, opens up a browser
selenium2: ~
symfony2: # bleeding fast, CLI, no browser
symfony2: ~
Scenario: Clicking on the submit button with good credentials
When I fill in "_username" with "mylogin"
And I fill in "_password" with "mypassword"
Then I press "Login"
And print last response
Then I should be on "/login_check"
When I do a And print last response in my behat feature config file, I have this error:
Your session has timed
out, or you have disabled cookies.
The result of the feature:
Then I should be on "/login_check"
Current page is "/<internalURL>/app_test.php/login",
but "/<internalURL>/app_test.php/login_check" expected.
(Behat\Mink\Exception\ExpectationException)
In order to test this behavior you can create this method :
/**
* #When I restart the browser
*/
public function restartBrowser()
{
$rememberMe = $this->getSession()->getCookie('REMEMBER_ME');
$this->getSession()->restart();
$this->visitPath('/');
$this->getSession()->setCookie('REMEMBER_ME', $rememberMe);
}
Please note that the cookie can be prefix by something like the name of your application if you have the framework.session.name set.
So REMEMBER_ME can be YOURAPP_REMEMBER_ME
So here an exemple of usage :
Scenario: I can remember my login in my browser
Given I fill in "_username" with "username"
And I fill in "_password" with "password"
And I check "Remember me?"
And I press "Login"
Then I should be on my account homepage
When I restart the browser
And I go to "/"
And I should see 1 "body.logged-in" elements
Hope it's useful.
Best regards.

How can I test a page behind a security firewall in Symfony?

In Symfony's cookbook, there is a page entitled How to Simulate Authentication with a Token in a Functional Test. In it, it is said that:
The technique described in How to Simulate HTTP Authentication in a Functional Test is cleaner and therefore the preferred way.
Also, on the page that the quotation above links to, the documentation says:
The trick is to include the http_basic key in your firewall, along with the form_login key
This tells me that it is all right to have the form_login key, along with the http_basic key, and somehow http_basic should take precedence.
Here is my config_test.yml configuration file:
imports:
- { resource: config_dev.yml }
framework:
test: ~
session:
storage_id: session.storage.mock_file
profiler:
collect: false
web_profiler:
toolbar: false
intercept_redirects: false
swiftmailer:
disable_delivery: true
liip_functional_test:
cache_sqlite_db: true
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_sqlite
path: %kernel.cache_dir%/test.db
security:
firewalls:
default:
http_basic: ~
However, when I open my application in the test environment, I still get redirected to the login_form URL.
Why isn't setting the http_basic acting like the documentation says it should, namely it getting activated rather than form_login?
As commented here, having the code I pasted in my original question works just fine. The reason it is loading the login form is because I am not logging in via http_basic. In other words, when I have both form_login and http_basic enabled, I can login both by providing the PHP_AUTH_USER/PHP_AUTH_PASSWORD, and by logging in through the form. In effect, I don't need different security_*.yml files; I just need to add http_basic: ~ to the already-defined firewall.
Just split security.yml to security_test.yml and security_prod.yml.
In security_test.yml put default security configuration (as delivered with Symfony) or other one, which doesn't have firewall restrictions.
Create a specific config file for test environment, like config_test.yml with
imports:
- { resource: config.yml }
- { resource: security_test.yml }
note here config.yml itself doesn't have any security imports, because You will receive some Exception about overriding security directive or smth.
Create a separate config_prod.yml with
imports:
- { resource: config.yml }
- { resource: security_prod.yml }
Now You have separate security for test and prod environments.
If Your environment naming is good, then Kernel will pick config_test.yml only when tests are executed. For development environment Your should use config_dev.yml instead of config_test.yml

Installation HWIOAuthBundle?

I try 10 times to find out how to install HWIOAuthBundle But there is no enough documentation,
I install the Bundle and I follow exactly the documentation in Git But it shows me this error:
InvalidConfigurationException: Unrecognized options "anonymous" under "security.firewalls.secured_area.oauth"
Somehow I didn't understand the Part A) 'Have a user provider that implements'.What should I do?Or where can I find easy documentation
A) Have a user provider that implements OAuthAwareUserProviderInterface
The bundle needs a service that is able to load users based on the user response of the oauth endpoint. If you have a custom service it should implement the interface: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthAwareUserProviderInterface.
The HWIOAuthBundle also ships with three default implementations:
OAuthUserProvider (service name: hwi_oauth.user.provider) - doesn't persist users
EntityUserProvider (service name: hwi_oauth.user.provider.entity) - loads users from a database
FOSUserBundle integration (service name: hwi_oauth.user.provider.fosub_bridge). Checkout the documentation for integrating HWIOAuthBundle with FOSUserBundle for more information: (todo)
what should I do here ?
You should replace/comment out the line of the service:
oauth_user_provider:
service: my.oauth_aware.user_provider.service
and then replace by:
oauth_user_provider:
oauth: ~
Source: https://github.com/hwi/HWIOAuthBundle/issues/72
Go further:
https://gist.github.com/danvbe/4476697
http://m2mdas.github.io/blog/2013/11/21/integrate-hwioauthbundle-with-fosuserbundle/
Ahh, seems like a typo in docs, could you move that anonymous 4 spaces lower to something like:
# app/config/security.yml
security:
firewalls:
secured_area:
anonymous: ~
oauth:
resource_owners:
facebook: "/login/check-facebook"
login_path: /login
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
Easy fix for this is to define a service like this :
In security.yml keep this :
oauth_user_provider:
service: my.oauth_aware.user_provider.service
In services.yml put this :
services:
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments:
userManager: "#fos_user.user_manager"
properties: ["pass properties as array"]
Thats it !

Symfony Doctrine generate entities from multiple databases

With Doctrine in Symfony2 there is a simple way to start a project with reverse-engineered Entities created from existing database schema. It is quite well documented here. There is not mentioned how to reverse-engineer data from a non-default database when using multiple databases (which is documented here).
I found the solution here, it works like this:
php app/console doctrine:mapping:convert --em="troller" --from-database yml ./src/NAMESPACE/NAMEBundle/Resources/config/doctrine/metadata/orm
However, I'm just getting the exception as if the second entity manager didn't exist. Even though I have config.yml according to docs.
[InvalidArgumentException]
Doctrine ORM Manager named "troller" does not exist.
Any ideas?
Did you specify an entity manager with "troller" name?
You can do this with a snippet of code like this (into app/config/config.yml file)
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
AcmeDemoBundle: ~
AcmeStoreBundle: ~
troller:
connection: troller
mappings:
YourTrollerBundle: ~
In this example, you've defined two entity managers called default and troller. The default entity manager manages entities in the AcmeDemoBundle and AcmeStoreBundle, while the troller entity manager manages entities in the YourTrollerBundle. You've also defined two connections, one for each entity manager.
Obiously define a new connection and entity manager, isn't enaugh: you have to specify "connection parameters" also (like db name, user, password, driver, and so on)
troller:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8

Symfony2 configure DB storage sessions

UPDATE: problem solved, see the comments (many issues, the versions differences was but one of them).
I'm trying to configure sessions in Symfony2 in config.yml file. I have the following configuration:
session:
default_locale: %locale%
lifetime: 7200
auto_start: true
storage_id: session.storage.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
pdo:
class: PDO
arguments:
- "mysql:dbname=%database_name%"
- %database_user%
- %database_password%
session.storage.pdo:
class: Symfony\Component\HttpFoundation\SessionStorage\PdoSessionStorage
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
It's based on Symfony2's cookbook http://symfony.com/doc/2.0/cookbook/configuration/pdo_session_storage.html
I've created exactly the same table as in the given link.
However, it doesn't work. I get some "blank" error (no error message, but "PDO Exception" and "Error Exception"). I admit I have no much knowledge on configuring the Symfony2 or any info (that's why I'm using cookbook). I lost a lot of time and see no much documentation about it in the internet, not mentioning the fact that internet is quite silent about this case (having session storaged to DB table in Symfony2).
My NetBeans is "shouting" sth about the last line:
arguments: [#pdo, %session.storage.options%, %pdo.db_options%]
"ScannerException while scanning for the next token we had this found character #(64) that cannot start any token".
UPDATE:
Hmm now I'm not sure if it's about the configuration. I can see that Symfony2's cookbook (use... ) example doesn't match actually the file structure in the Symfony2's bundle. In a word, there is no such file-path, but after putting the real one it still doesn't work.
I had the same problem as you with Symfony 2.5. Turns out my solution was to disable session.auto_start in php.ini. The PdoSessionStorage will not take over if the session is being started before PDO has the opportunity to take control of it. I had overlooked this at first because I was modifying the wrong one (I had two copies of php.ini). To check if this is the problem on yours, run this command:
echo ini_get('session.auto_start');
If that returns a '1' or a 'true', then be sure to set this in your php.ini:
session.auto_start = 0
So for reference, here is my setup with Symfony 2.5 to make this work:
config.yml
framework:
session:
handler_id: session.handler.pdo
parameters:
pdo.db_options:
db_table: session
db_id_col: session_id
db_data_col: session_value
db_time_col: session_time
services:
session.handler.pdo:
class: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler
arguments: ["#pdo", "%pdo.db_options%"]
pdo:
class: PDO
arguments:
dsn: "mysql:host=%database_host%;port=%database_port%;dbname=%database_name%"
user: "%database_user%"
password: "%database_password%"
calls:
- [setAttribute, [3, 2]] # \PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION

Resources