I'm trying to follow this documentation, but the yaml config throws some errors.
I'm don't know Symfony enough to understand what I am doing wrong.
https://github.com/scheb/2fa/blob/5.x/doc/providers/email.md
services.yaml:
https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
uploads_path: '/uploads/files/'
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
- '../src/Tests/'
App\Controller\:
resource: '../src/Controller/'
tags: ['controller.service_arguments']
# App\Service\CodeGeneratorService:
# arguments: ['#markdown.parser', '#doctrine_cache.providers.my_markdown_cache']
auth_mailer:
# class: Scheb\TwoFactorBundle\Mailer\SymfonyAuthCodeMailer
class: App\Mailer\MyAuthCodeMailer
code_generator_service:
class: App\Service\CodeGeneratorService
# public: true
arguments:
# $mailer: "%scheb_two_factor.security.email.symfony_auth_code_mailer%"
# $mailer: "%scheb_two_factor.security.email.swift_auth_code_mailer%"
# $mailer: App\Mailer\MyAuthCodeMailer
# $mailer: Scheb\TwoFactorBundle\Mailer\SymfonyAuthCodeMailer
# $mailer: Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface
# $mailer: App\service\CodeGeneratorService
# $mailer: "%scheb_two_factor.email.mailer%"
$digits: "%scheb_two_factor.email.digits%"
scheb_2fa.yaml:
# See the configuration reference at https://github.com/scheb/2fa/blob/master/doc/configuration.md
scheb_two_factor:
security_tokens:
- Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken
email:
enabled: true
sender_email: quezako35#gmail.com
sender_name: Quezako # Optional
digits: 12
code_generator: code_generator_service # Use alternative service to generate authentication code
mailer: auth_mailer # Use alternative service to send the authentication code
App\Service\CodeGeneratorService.php:
<?php
declare(strict_types=1);
namespace App\Service;
use Scheb\TwoFactorBundle\Model\PersisterInterface;
use Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface;
use Scheb\TwoFactorBundle\Security\TwoFactor\Provider\Email\Generator\CodeGeneratorInterface;
class CodeGeneratorService implements CodeGeneratorInterface
{
/**
* #var PersisterInterface
*/
private $persister;
/**
* #var AuthCodeMailerInterface
*/
private $mailer;
/**
* #var int
*/
private $digits;
public function __construct(PersisterInterface $persister, AuthCodeMailerInterface $mailer, int $digits)
{
$this->persister = $persister;
$this->mailer = $mailer;
$this->digits = $digits;
}
public function generateAndSend(TwoFactorInterface $user): void
{
$min = 10 ** ($this->digits - 1);
$max = 10 ** $this->digits - 1;
$code = $this->generateCode($min, $max);
$user->setEmailAuthCode((string) $code);
$this->persister->persist($user);
$this->mailer->sendAuthCode($user);
}
public function reSend(TwoFactorInterface $user): void
{
$this->mailer->sendAuthCode($user);
}
protected function generateCode(int $min, int $max): string
{
return substr(md5(rand()), $min, $max);
}
}
The various error messages I get:
Cannot autowire service "code_generator_service": argument "$mailer" of method "App\Service\CodeGeneratorService::__construct()" references interface "Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface" but no such service exists. You should maybe alias this interface to one of these existing services: "App\Mailer\MyAuthCodeMailer", "auth_mailer", "scheb_two_factor.security.email.swift_auth_code_mailer", "scheb_two_factor.security.email.symfony_auth_code_mailer".
You have requested a non-existent parameter "scheb_two_factor.email.mailer". Did you mean one of these: "scheb_two_factor.email.sender_name", "scheb_two_factor.email.template", "scheb_two_factor.email.digits"?
Argument 2 passed to App\Service\CodeGeneratorService::__construct() must implement interface Scheb\TwoFactorBundle\Mailer\AuthCodeMailerInterface, string given, called in D:\Dev\meet_the_team\var\cache\dev\Container0FXY0Rx\srcApp_KernelDevDebugContainer.php on line 621
The author, Christian Scheb, gave me the answer.
You have to configure a service and reference that service using the # annotation to tell Symfony to use that service instance.
https://github.com/scheb/2fa/issues/22
services:
# ...
auth_mailer:
class: App\Mailer\MyAuthCodeMailer
code_generator_service:
class: App\Service\CodeGeneratorService
arguments:
$mailer: "#auth_mailer"
$digits: "%scheb_two_factor.email.digits%"
I'm working on a symfony project that need to be refactorized.
I'm trying to call a environnement variable declared in servces.yml
When i'm running php bin/console debug:container --parameters I can see the variables.
I tried $this->getParameters('param_name');
When I'm dumping them in a controller it's working fine but when i'm trying to access them from a service it is failing -> Method 'getParameter' not found in 'TwitterService'
I thought that this method was native in symfony.
Here is my twitter service
```namespace App\Services;
use Abraham\TwitterOAuth\TwitterOAuth;
/**
* Class TwitterService.
*/
class TwitterService
{
/** #const int NUMBER_OF_TWEETS */
private const NUMBER_OF_TWEETS = 2;
/**
* #param string $twitterID
*
* #return array|object
*/
public function getTwitterFeed($twitterID = 'RISKandMe')
{
// #todo move config to .env
$consumerKey = $this->getParameter('consumer_key');
$consumerSecret = $this->getParameter('consumer_secret');
$accessToken = $this->getParameter('access_token');
$accessTokenSecret = $this->getParameter('access_token');
// Authenticate with twitter
$twitterConnection = new TwitterOAuth(
$consumerKey,
$consumerSecret,
$accessToken,
$accessTokenSecret
);
// Get the user timeline feeds
return $twitterConnection->get(
'statuses/user_timeline',
[
'screen_name' => $twitterID,
'count' => self::NUMBER_OF_TWEETS,
'exclude_replies' => false,
]
);
}
}
Here is my services.yml:
parameters:
locale: 'fr'
api_key_validity: '%env(int:APIKEYVALIDITY)%'
activation_delay: '%env(int:ACTIVATIONDELAY)%'
gophish_api_key: '%env(GOPHISHAPIKEY)%'
gophish_server: '%env(GOPHISHSERVER)%'
gophish_white_list: '%env(GOPHISHWHITELIST)%'
mailjet_public: '%env(MAILJET_PUBLIC_KEY)%'
mailjet_secret: '%env(MAILJET_PRIVATE_KEY)%'
sender_address: '%env(SENDER_ADDRESS)%'
sender_name: '%env(SENDER_NAME)%'
consumer_key: '%env(CONSUMER_KEY)%'
consumer_secret: '%env(CONSUMER_SECRET)%'
access_token: '%env(ACCESS_TOKEN)%'
access_token_secret: '%env(ACCESS_TOKEN_SECRET)%'
services:
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
# user_listener:
# class: App\EntityListener\UserListener
# arguments: ['#logger']
# tags:
# - { name: doctrine.orm.entity_listener,entity: App\Entity\User}
#
form_authenticator:
class: App\Security\FormAuthenticator
arguments: ["#logger","#router","#security.password_encoder","#doctrine.orm.default_entity_manager",CsrfTokenManagerInterface]
token_authenticator:
class: App\Security\TokenAuthenticator
arguments: ["#logger","#router","#security.password_encoder","#doctrine.orm.default_entity_manager",CsrfTokenManagerInterface,ParameterBagInterface]
DbUserProvider:
class: App\Security\DbUserProvider
FickleUserProvider:
class: App\Security\FickleUserProvider
BackEndUserProvider:
class: App\Security\BackEndUserProvider
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\Services\Helper:
arguments: ['#logger','#router','#security.password_encoder','#mailer','#session','#doctrine.orm.default_entity_manager']
tags: ['controller.service_arguments']
App\Controller\Services\GoPhish:
arguments: []
tags: []
App\Controller\:
resource: '../src/Controller/DashboardController.php'
arguments: ["#logger","#router","#security.password_encoder",'#doctrine.orm.default_entity_manager',App\Controller\Services\Helper]
tags: ['controller.service_arguments']
twig.extension.intl:
class: Twig_Extensions_Extension_Intl
tags:
- { name: twig.extension }
# session.listener:
# class: App\Listeners\SessionListener
# tags:
# - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
# user.activity_listener:
# class: App\Listeners\ActivityListener
# tags:
# - { name: kernel.event_listener, event: kernel.controller, method: onCoreController }
Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler:
arguments:
- '%env(string:DBCONNEXIONPARAMETERS)%'
- { db_table: 'ht_session', db_username: '%env(string:DBUSER)%', db_password: '%env(string:DBPASSWORD)%'}
app.services.twitter:
class: App\Services\TwitterService
If someone has any idea they would be more than appreciated.
Thank you very much for you attention.
The $this->getParameter() helper function is only available in controllers extending from the class Symfony\Bundle\FrameworkBundle\Controller\AbstractController;.
In order to access a container-parameter in your service you need to inject or autowire it into your service.
# services.yml
services:
_defaults:
bind:
# schema -> [constructor-variable name]: [parameter name]
$consumerSecret: '%consumer_secret%'
$consumerKey: '%consumer_key%'
# [..]
Then use them as follows:
class TwitterService
{
private $csonsumerSecret;
private $consumerKey;
public function __construct(
string $consumerKey,
string $consumerSecret,
// [..]
) {
$this->consumerKey = $consumerKey;
$this->consumerSecret = $consumerSecret;
// [..]
}
public function getTwitterFeed($twitterID = 'RISKandMe')
{
$twitterConnection = new TwitterOAuth(
$this->consumerKey,
$this->consumerSecret,
// [..]
);
I have migrated a symfony 4 application from the production server to the server that I am using for tests, bothe servers are on wampserver . the application works fine on the test server but the problem is that when I make changes, they are not taken into account. every time I change a twig file the changes dont show up. I think that it is using the prod and dev variables but I am new in Symfony I am not sure how it works .apparently now the server is on prod mode and I want to change it to dev mode .
the code for the vhosts file is
# Virtual Hosts
#
<VirtualHost *:80>
ServerName localhost
ServerAlias localhost
SetEnv APP_ENV prod
SetEnv APP_SECRET b33c77e602bc1bafb66f673c1e31aca3
SetEnv DATABASE_URL mysql://root#127.0.0.1:3306/gpac
DocumentRoot "${INSTALL_DIR}/www/gpac/public"
<Directory "${INSTALL_DIR}/www/gpac/public/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
the public/index.php is
<?php
use App\Kernel;
use Symfony\Component\Debug\Debug;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpFoundation\Request;
require __DIR__.'/../vendor/autoload.php';
// The check is to ensure we don't use .env in production
if (!isset($_SERVER['APP_ENV'])) {
if (!class_exists(Dotenv::class)) {
throw new \RuntimeException('APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.');
}
(new Dotenv())->load(__DIR__.'/../.env');
}
$env = $_SERVER['APP_ENV'] ?? 'dev';
$debug = (bool) ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env));
if ($debug) {
umask(0000);
Debug::enable();
}
if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? false) {
Request::setTrustedProxies(explode(',', $trustedProxies), Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST);
}
if ($trustedHosts = $_SERVER['TRUSTED_HOSTS'] ?? false) {
Request::setTrustedHosts(explode(',', $trustedHosts));
}
$kernel = new Kernel($env, $debug);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
when I run the php bin/console cache:clear --env=prod it gives an error because the .env file does not exist
the code for config/services.yaml is
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: 'fr'
version: 1.0.0
default_alert:
council_meeting: 7 # days
project_step: 7 # days
resource_report: 1 # years
resource_contract: 1 # month
resource_capability: 1 # month
services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
public: false # Allows optimizing the container by removing unused services; this also means
# fetching services directly from the container via $container->get() won't work.
# The best practice is to be explicit about your dependencies anyway.
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'
# controllers are imported separately to make sure services can be injected
# as action arguments even if you don't extend any base controller class
App\Controller\:
resource: '../src/Controller'
tags: ['controller.service_arguments']
# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
activity:
class: App\Service\ActivityLogger
public: true
arguments: ['#doctrine.orm.entity_manager', '#security.token_storage', '#request_stack']
process:
class: App\Service\ProcessProvider
public: true
arguments: ['%kernel.project_dir%']
App\Listener\LoginListener:
arguments: ['#activity']
tags:
- { name: kernel.event_subscriber }
dpolac.twig_lambda.extension:
class: DPolac\TwigLambda\LambdaExtension
tags: [ { name: twig.extension } ]
# ---------------------
# Sonata Admin Services
# ---------------------
app.admin.user:
public: true
class: App\Admin\UserAdmin
arguments: [~, App\Entity\User, App\Controller\UserAdminController]
tags:
- { name: sonata.admin, manager_type: orm, group: admin, label: class.User }
app.admin.user_function:
public: true
class: App\Admin\UserFunctionAdmin
arguments: [~, App\Entity\UserFunction, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: admin, label: class.UserFunction }
app.admin.skill_matrix:
class: App\Admin\SkillMatrixAdmin
arguments: [~, App\Entity\SkillMatrix, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.SkillMatrix }
app.admin.skill_matrix_category:
class: App\Admin\SkillMatrixCategoryAdmin
arguments: [~, App\Entity\SkillMatrixCategory, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: skill, label: class.SkillMatrixCategory }
calls:
- [ setTemplate, [list, 'CRUD/Skill/list.html.twig']]
app.admin.client:
class: App\Admin\ClientAdmin
arguments: [~, App\Entity\Client, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: project, label: class.Client }
calls:
- [addChild, ['#app.admin.client_site']]
app.admin.client_site:
class: App\Admin\ClientSiteAdmin
arguments: [~, App\Entity\ClientSite, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ClientSite}
app.admin.client_numbers:
class: App\Admin\ClientNumbersAdmin
arguments: [~, App\Entity\ClientNumbers, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ClientNumbers}
app.admin.resource:
class: App\Admin\ResourceAdmin
arguments: [~, App\Entity\Resource, SonataAdminBundle:CRUD, '#doctrine.orm.entity_manager']
tags:
- { name: sonata.admin, manager_type: orm, group: rc, label: class.Resource }
public: true
calls:
- [ setTemplate, [show, 'CRUD/Resource/show.html.twig']]
- [addChild, ['#app.admin.resource_capability']]
- [addChild, ['#app.admin.resource_contract']]
- [addChild, ['#app.admin.resource_education']]
- [addChild, ['#app.admin.resource_experience']]
- [addChild, ['#app.admin.resource_lang']]
- [addChild, ['#app.admin.resource_report']]
app.admin.council:
public: true
class: App\Admin\CouncilAdmin
arguments: [~, App\Entity\Council, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: council, label: class.Council }
calls:
- [ setTemplate, [list, 'CRUD/Council/list.html.twig']]
app.admin.council_meeting:
class: App\Admin\CouncilMeetingAdmin
arguments: [~, App\Entity\CouncilMeeting, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: council, label: class.CouncilMeeting }
public: true
app.admin.resource_capability:
class: App\Admin\ResourceCapabilityAdmin
arguments: [~, App\Entity\ResourceCapability, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm , label: class.ResourceCapability}
public: true
app.admin.resource_contract:
class: App\Admin\ResourceContractAdmin
arguments: [~, App\Entity\ResourceContract, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ResourceContract}
public: true
app.admin.resource_education:
class: App\Admin\ResourceEducationAdmin
arguments: [~, App\Entity\ResourceEducation, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm , label: class.ResourceEducation}
public: true
app.admin.resource_experience:
class: App\Admin\ResourceExperienceAdmin
arguments: [~, App\Entity\ResourceExperience, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm , label: class.ResourceExperience}
public: true
app.admin.resource_lang:
class: App\Admin\ResourceLangAdmin
arguments: [~, App\Entity\ResourceLang, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ResourceLang}
public: true
app.admin.project:
class: App\Admin\ProjectAdmin
arguments: [~, App\Entity\Project, App\Controller\ProjectAdminController]
tags:
- { name: sonata.admin, manager_type: orm, group: project, label: class.Project }
public: true
calls:
- [setTemplate, ['list', 'CRUD/Project\list.html.twig']]
- [setTemplate, ['show', 'CRUD/Project\show.html.twig']]
- [setTemplate, ['edit', 'CRUD/Project\edit.html.twig']]
- [addChild, ['#app.admin.project_eval']]
- [addChild, ['#app.admin.project_status']]
- [addChild, ['#app.admin.project_alert']]
app.admin.project_status:
class: App\Admin\ProjectStatusAdmin
arguments: [~, App\Entity\ProjectStatus, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ProjectStatus }
public: true
app.admin.project_eval:
class: App\Admin\ProjectEvalAdmin
arguments: [~, App\Entity\ProjectEval, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ProjectEval }
public: true
calls:
- [addChild, ['#app.admin.project_step']]
- [addChild, ['#app.admin.project_staff']]
app.admin.project_staff:
class: App\Admin\ProjectStaffAdmin
arguments: [~, App\Entity\ProjectStaff, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ProjectStaff }
public: true
app.admin.project_step:
class: App\Admin\ProjectStepAdmin
arguments: [~, App\Entity\ProjectStep, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ProjectStep }
public: true
app.admin.activity:
class: App\Admin\ActivityAdmin
arguments: [~, App\Entity\Activity, App\Controller\ActivityAdminController]
tags:
- { name: sonata.admin, manager_type: orm, group: admin, label: class.Activity }
public: true
app.admin.project_alert:
class: App\Admin\ProjectAlertAdmin
arguments: [~, App\Entity\ProjectAlert, App\Controller\ProjectAlertAdminController]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ProjectAlert }
public: true
app.admin.report_qual_theo:
class: App\Admin\ReportQualTheoAdmin
arguments: [~, App\Entity\ReportQualTheo, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: frc, label: class.ReportQualTheo }
public: true
app.admin.report_qual_prat:
class: App\Admin\ReportQualPratAdmin
arguments: [~, App\Entity\ReportQualPrat, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: frc, label: class.ReportQualPrat }
public: true
app.admin.resource_report:
class: App\Admin\ResourceReportAdmin
arguments: [~, App\Entity\ResourceReport, App\Controller\ResourceReportAdminController]
tags:
- { name: sonata.admin, manager_type: orm, group: frc, label: class.ResourceReport }
public: true
calls:
- [addChild, ['#app.admin.resource_report_education']]
- [addChild, ['#app.admin.resource_report_forum']]
- [addChild, ['#app.admin.resource_report_project']]
app.admin.resource_report_education:
class: App\Admin\ResourceReportEducationAdmin
arguments: [~, App\Entity\ResourceReportEducation, App\Controller\ResourceReportEducationAdminController]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ResourceReportEducation }
public: true
app.admin.resource_report_forum:
class: App\Admin\ResourceReportForumAdmin
arguments: [~, App\Entity\ResourceReportForum, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ResourceReportForum }
public: true
app.admin.resource_report_project:
class: App\Admin\ResourceReportProjectAdmin
arguments: [~, App\Entity\ResourceReportProject, App\Controller\ResourceReportProjectAdminController]
tags:
- { name: sonata.admin, manager_type: orm, label: class.ResourceReportProject }
public: true
calls:
- ['setTemplate', ['list', 'CRUD/ReportResourceProject\list.html.twig']]
app.admin.report_council:
class: App\Admin\ReportCouncilAdmin
arguments: [~, App\Entity\ReportCouncil, SonataAdminBundle:CRUD]
tags:
- { name: sonata.admin, manager_type: orm, group: frc, label: class.ReportCouncil }
public: true
For symfony4 console the environment variables given in .htaccess or in webserver has no effect. so you need to provide the environment variable with the command.
You should run following command to clear cache in production
APP_ENV=prod php bin/console cache:clear
If you are running command from windows cmd then you may need to run like:
set APP_ENV=prod php bin/console cache:clear
You could try changing the 'SetEnv APP_ENV prod' to 'SetEnv APP_ENV dev' in your VirtualHost file.
# Virtual Hosts
#
<VirtualHost *:80>
ServerName localhost
ServerAlias localhost
SetEnv APP_ENV dev #<-------------------------------------- here
SetEnv APP_SECRET b33c77e602bc1bafb66f673c1e31aca3
SetEnv DATABASE_URL mysql://root#127.0.0.1:3306/gpac
DocumentRoot "${INSTALL_DIR}/www/gpac/public"
<Directory "${INSTALL_DIR}/www/gpac/public/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
So i'm trying to use the HWI-OAuthBundle and FoS-UserBundle in order to enable users to connect from our schools credentials. So I applied what was said in the docs and configured the custom resource owner.
When i try to login, i'm correctly redirected to the schools OAuth service where i login & authorize the client to access my profile but then i have this error message :
No property defined for entity for resource owner 'myecp'.
I tried several solutions I found on internet, none of them works for me.
Here is my code :
config.yml
#HWIOAuthBundle
hwi_oauth:
connect:
account_connector: my.myecp.user_provider
firewall_names: [secured_area]
fosub:
username_iterations: 30
properties:
myecp: myecp_id
resource_owners:
myecp:
type: oauth2
client_id: "%myecp_client_id%"
client_secret: "%myecp_secret%"
access_token_url: https://my.ecp.fr/oauth/v2/token
authorization_url: https://my.ecp.fr/oauth/v2/auth
infos_url: https://my.ecp.fr/api/v1/members/me
user_response_class: HWI\Bundle\OAuthBundle\OAuth\Response\PathUserResponse
paths:
identifier: id
nickname: login
realname: [first_name, last_name]
mail: mail
options:
csrf: true
#FOSUserBundle
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\Personnes
from_email:
address: "%mailer_user%"
sender_name: "%mailer_user%"
#Services
services:
my.myecp.user_provider:
class: AppBundle\Security\Core\User\FOSUBPersonnesProvider
arguments: ['#fos_user.user_manager', { myecp: myecp_id }]
security.yml :
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
fos_userbundle:
id: fos_user.user_provider.username
# in_memory:
# memory: ~
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
secured_area:
anonymous: ~
oauth:
resource_owners:
myecp: "/login/check"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
main:
# anonymous: ~
# activate different ways to authenticate
# http_basic: ~
# http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# http://symfony.com/doc/current/cookbook/security/form_login_setup.html
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
logout: true
anonymous: true
access_control:
- { path: ^/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
services.yml:
services:
# service_name:
# class: AppBundle\Directory\ClassName
# arguments: ["#another_service_name", "plain_value", "%parameter_name%"]
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments:
- '#fos_user.user_manager'
- ['pass properties as array']
routing.yml:
app:
resource: "#AppBundle/Controller/"
type: annotation
hwi_oauth_redirect:
resource: "#HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /connect
hwi_oauth_connect:
resource: "#HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect
hwi_oauth_login:
resource: "#HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /login
fos_user:
resource: "#FOSUserBundle/Resources/config/routing/all.xml"
myecp_login:
path: /login/check
logout:
path: /logout
FOSUBPersonnesProvider.php
class FOSUBPersonnesProvider extends BaseFOSUBProvider
{
/**
* {#inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
// get property from provider configuration by provider name
// , it will return `myecp_id` in that case (see service definition below)
$property = $this->getProperty($response);
$username = $response->getUsername(); // get the unique user identifier
//on connect - get the access token and the user ID
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
//we "disconnect" previously connected users
$existingUser = $this->userManager->findUserBy(array($property => $username));
if (null !== $existingUser) {
$existingUser->$setter_id(null);
$existingUser->$setter_token(null);
$this->userManager->updateUser($existingUser);
}
$user->$setter_id($username);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {#inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$userId = $response->getUsername();
$user = $this->userManager->findUserBy(array('myecpId' => $userId));
// if null just create new user and set it properties
if (null === $user) {
$first_name = $response->getFirstName();
$last_name = $response->getLastName();
$email = $response->getEmail();
$service = $response->getResourceOwner()->getName();
$setter = 'set'.ucfirst($service);
$setter_id = $setter.'Id';
$setter_token = $setter.'AccessToken';
// create new user here
$user = $this->userManager->createUser();
$user->setPrenom($first_name);
$user->setNom($last_name);
$user->setMail($email);
$user->$setter_id($userId);
$user->$setter_token($response->getAccessToken());
$this->userManager->updateUser($user);
return $user;
}
// else update access token of existing user
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
$user->$setter($response->getAccessToken());//update access token
return $user;
}
}
Thanks for your help !
First change in file services.yml line where You pass argument for user.provider.
For example change last line, below is my working example for google.
my.custom.user_provider:
class: YOURBUNDLENAME\Security\Core\MyFOSUBUserProvider
arguments:
- '#fos_user.user_manager'
- arguments: **[ #fos_user.user_manager, { google: googleID }** ]
Next change $property to name of User entity property name ( myecp ?? ) . In my exmaple its googleID. $property is in FOSUBPersonnesProvider.php below connect() method.
My User.php entity looks like:
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var string
*
* #ORM\Column(name="google_id", type="string", nullable=true)
*/
private $googleID;
I hope this will help you
I solved this problem.
Because here passing arguments as array:
arguments: ['#fos_user.user_manager', { myecp: myecp_id }] //In Service
Change to :
arguments: ['#fos_user.user_manager', myecp: myecp_id ]
When send second parameter in FOSUserProvider merging array HERE
Then ERROR message showing HERE
protected function getProperty(UserResponseInterface $response)
{
$resourceOwnerName = $response->getResourceOwner()->getName();
if (!isset($this->properties[$resourceOwnerName])) {
throw new \RuntimeException(sprintf("No property defined for entity for resource owner '%s'.", $resourceOwnerName));
}
return $this->properties[$resourceOwnerName];
}
If you are using Facebook:
arguments: ['#fos_user.user_manager', facebook: facebook ]
If you are using amazon:
arguments: ['#fos_user.user_manager', amazon: amazon ]
If you are using Odnoklassniki:
arguments: ['#fos_user.user_manager', odnoklassniki: odnoklassniki ]
If you are using github:
arguments: ['#fos_user.user_manager', github: github ]
If you are using google:
arguments: ['#fos_user.user_manager', google: google ]
.. What's up guys I've doing this project with Symfony 2.3.5 using FOSUSer Bundel and PUGXMultiUser Bundle and I wanted to use SonataAdmin Bundle but after configuration there was this problem about Menu that I could'nt see in the Dashboard .. Here is the configuration do you think I missed something !!
config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: #PokTVBundle/Resources/config/admin.yml }
framework:
#esi: ~
translator: { fallback: %locale% }
secret: %secret%
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_proxies: ~
session: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
# Assetic Configuration
assetic:
debug: %kernel.debug%
use_controller: false
bundles: [ ]
#java: /usr/bin/java
filters:
cssrewrite: ~
#closure:
# jar: %kernel.root_dir%/Resources/java/compiler.jar
#yui_css:
# jar: %kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar
# Doctrine Configuration
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
port: %database_port%
dbname: %database_name%
user: %database_user%
password: %database_password%
charset: UTF8
# if using pdo_sqlite as your database driver, add the path in parameters.yml
# e.g. database_path: %kernel.root_dir%/data/data.db3
# path: %database_path%
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: %mailer_transport%
host: %mailer_host%
username: %mailer_user%
password: %mailer_password%
spool: { type: memory }
#FOSBundle
fos_user:
db_driver: orm # other valid values are 'mongodb', 'couchdb' and 'propel'
firewall_name: main
user_class: POKEtudiant\UserBundle\Entity\User
service:
mailer: fos_user.mailer.twig_swift
user_manager: pugx_user_manager
#registration:
#confirmation:
#enabled: true
#from_email:
#address: noreply#POKEtudiant.com
#sender_name: Elamrani Abou Elassad
#PUGXBundle
pugx_multi_user:
users:
etudiants:
entity:
class: POKEtudiant\UserBundle\Entity\Etudiant
# factory:
registration:
form:
type: POKEtudiant\UserBundle\Form\Type\RegistrationEtudiantFormType
name: fos_user_registration_form
validation_groups: [etudiant_grp, Default]
template: UserBundle:Registration:etudiants.form.html.twig
profile:
form:
type: POKEtudiant\UserBundle\Form\Type\ProfileEtudiantFormType
name: fos_user_profile_form
#validation_groups: [Profile, Default]
recruteurs:
entity:
class: POKEtudiant\UserBundle\Entity\Recruiter
registration:
form:
type: POKEtudiant\UserBundle\Form\Type\RegistrationRecruiterFormType
template: UserBundle:Registration:recruteurs.form.html.twig
profile:
form:
type: POKEtudiant\UserBundle\Form\Type\ProfileRecruiterFormType
#SonataBlock
sonata_block:
default_contexts: [cms]
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
#sonata.admin_doctrine_orm.block.audit:
# contexts: [admin]
sonata.block.service.text:
sonata.block.service.rss:
# Some specific block from the SonataMediaBundle
#sonata.media.block.media:
#sonata.media.block.gallery:
#sonata.media.block.feature_media:
#SonataKnp
knp_menu:
twig: # use "twig: false" to disable the Twig extension and the TwigRenderer
template: knp_menu.html.twig
templating: false # if true, enables the helper for PHP templates
default_renderer: twig # The renderer to use, list is also available by default
#SonataAdmin
sonata_admin:
title: PokTv
#title_logo: /bundles/acmedemo/fancy_acme_logo.png
#security:
#handler: sonata.admin.security.handler.noop
#acl_user_manager: fos_user.user_manager
templates:
# default global templates
layout: SonataAdminBundle::standard_layout.html.twig
ajax: SonataAdminBundle::ajax_layout.html.twig
dashboard: SonataAdminBundle:Core:dashboard.html.twig
# default actions templates, should extend a global templates
list: SonataAdminBundle:CRUD:list.html.twig
show: SonataAdminBundle:CRUD:show.html.twig
edit: SonataAdminBundle:CRUD:edit.html.twig
history: SonataAdminBundle:CRUD:history.html.twig
preview: SonataAdminBundle:CRUD:preview.html.twig
delete: SonataAdminBundle:CRUD:delete.html.twig
batch: SonataAdminBundle:CRUD:list__batch.html.twig
batch_confirmation: SonataAdminBundle:CRUD:batch_confirmation.html.twig
# list related templates
inner_list_row: SonataAdminBundle:CRUD:list_inner_row.html.twig
base_list_field: SonataAdminBundle:CRUD:base_list_field.html.twig
# default values of block templates, they should extend the base_block template
list_block: SonataAdminBundle:Block:block_admin_list.html.twig
dashboard:
blocks:
- { position: left, type: sonata.admin.block.admin_list }
# display two dashboard blocks
#-
#position: left
#type: sonata.admin.block.admin_list
#settings:
#groups: [Movies]
#-
#position: right
#type: sonata.admin.block.admin_list
#settings:
#groups: [Series]
groups:
Movies:
items:
- sonata.admin.movies
Series:
items:
- sonata.admin.series
Foot:
items:
- sonata.admin.foot
sonata_doctrine_orm_admin:
# default value is null, so doctrine uses the value defined in the configuration
entity_manager:
templates:
form:
- SonataDoctrineORMAdminBundle:Form:form_admin_fields.html.twig
filter:
- SonataDoctrineORMAdminBundle:Form:filter_admin_fields.html.twig
types:
list:
array: SonataAdminBundle:CRUD:list_array.html.twig
boolean: SonataAdminBundle:CRUD:list_boolean.html.twig
date: SonataAdminBundle:CRUD:list_date.html.twig
time: SonataAdminBundle:CRUD:list_time.html.twig
datetime: SonataAdminBundle:CRUD:list_datetime.html.twig
text: SonataAdminBundle:CRUD:base_list_field.html.twig
trans: SonataAdminBundle:CRUD:list_trans.html.twig
string: SonataAdminBundle:CRUD:base_list_field.html.twig
smallint: SonataAdminBundle:CRUD:base_list_field.html.twig
bigint: SonataAdminBundle:CRUD:base_list_field.html.twig
integer: SonataAdminBundle:CRUD:base_list_field.html.twig
decimal: SonataAdminBundle:CRUD:base_list_field.html.twig
identifier: SonataAdminBundle:CRUD:base_list_field.html.twig
show:
array: SonataAdminBundle:CRUD:show_array.html.twig
boolean: SonataAdminBundle:CRUD:show_boolean.html.twig
date: SonataAdminBundle:CRUD:show_date.html.twig
time: SonataAdminBundle:CRUD:show_time.html.twig
datetime: SonataAdminBundle:CRUD:show_datetime.html.twig
text: SonataAdminBundle:CRUD:base_show_field.html.twig
trans: SonataAdminBundle:CRUD:show_trans.html.twig
string: SonataAdminBundle:CRUD:base_show_field.html.twig
smallint: SonataAdminBundle:CRUD:base_show_field.html.twig
bigint: SonataAdminBundle:CRUD:base_show_field.html.twig
integer: SonataAdminBundle:CRUD:base_show_field.html.twig
decimal: SonataAdminBundle:CRUD:base_show_field.html.twig
admin.yml
services:
sonata.admin.movies:
class: POKEtudiant\PokTVBundle\Admin\MoviesAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Movies", label: "Movies", show_in_dashboard: "true" }
arguments:
- ~
- POKEtudiant\PokTVBundle\Entity\Movies
- ~
sonata.admin.series:
class: POKEtudiant\PokTVBundle\Admin\SeriesAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Series", label: "Series" }
arguments:
- ~
- POKEtudiant\PokTVBundle\Entity\Series
- ~
sonata.admin.foot:
class: POKEtudiant\PokTVBundle\Admin\FootAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: "Foot", label: "Foot" }
arguments:
- ~
- POKEtudiant\PokTVBundle\Entity\Foot
- ~
app/config/routing.yml
#PokTV Bundle
pok_tv:
resource: "#PokTVBundle/Resources/config/routing.yml"
prefix: /PokTV
#User Bundle
user:
resource: "#UserBundle/Resources/config/routing.yml"
prefix: /
#Sonata Admin
admin:
resource: '#SonataAdminBundle/Resources/config/routing/sonata_admin.xml'
prefix: /admin
_sonata_admin:
resource: .
type: sonata_admin
prefix: /admin
appKernel (registerBundles)
public function registerBundles()
{
$bundles = array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
new Symfony\Bundle\SecurityBundle\SecurityBundle(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
new Symfony\Bundle\MonologBundle\MonologBundle(),
new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
new Symfony\Bundle\AsseticBundle\AsseticBundle(),
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
new FOS\UserBundle\FOSUserBundle(),
new PUGX\MultiUserBundle\PUGXMultiUserBundle(),
new Sonata\BlockBundle\SonataBlockBundle(),
new Sonata\jQueryBundle\SonatajQueryBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
new Sonata\AdminBundle\SonataAdminBundle(),
new POKEtudiant\UserBundle\UserBundle(),
new POKEtudiant\PokTVBundle\PokTVBundle(),
);
if (in_array($this->getEnvironment(), array('dev', 'test'))) {
$bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
$bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
$bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
}
return $bundles;
}
It's looks like you have not configured ROLE_SONATA_ADMIN for your user;
Or just map it in security.yml, like this
security:
role_hierarchy:
ROLE_ADMIN: [ROLE_USER, ROLE_SONATA_ADMIN]
After your user will have this role, the menu must be displayed;
Check your twig file to see which block is still being used. The sonata blocks section only has sonata.admin.block.admin_list which should be loaded with the defaults.
You can get error feedback by enabling filters:
[sorry this is my first resonse. How do you get the formatting to work?]
sonata_block:
default_contexts: [cms]
exception:
default:
filter: debug_only
renderer: throw
filters:
debug_only: sonata.block.exception.filter.debug_only
ignore_block_exception: sonata.block.exception.filter.ignore_block_exception
keep_all: sonata.block.exception.filter.keep_all
keep_none: sonata.block.exception.filter.keep_none
renderers:
inline: sonata.block.exception.renderer.inline
inline_debug: sonata.block.exception.renderer.inline_debug
throw: sonata.block.exception.renderer.throw
Then add this line directly under the admin block:
blocks:
sonata.admin.block.admin_list:
contexts: [admin]
exception: { filter: keep_all, renderer: inline }