How to authorize custom user from db in Symfony4 - symfony

I just need to authorize custom user. Without any froms, tokens and etc. I have user entity in my DB.
User class is already configuren it fos_user.yaml:
fos_user:
db_driver: orm
firewall_name: main
from_email:
address: '***#*******.**'
sender_name: '**.****.**'
user_class: App\Entity\User
Is it possible? Somethong like
Authurizer::authorize($userEntity)
Thanks.

Authorization in Symfony done Tokens. To be logged in Symfony's World you'll need to set a Token.
One of the common use cases is "auto login" right after registration.
Take a look at this article -> https://ourcodeworld.com/articles/read/459/how-to-authenticate-login-manually-an-user-in-a-controller-with-or-without-fosuserbundle-on-symfony-3
especially for that part
$token = new UsernamePasswordToken($user, null, 'main', $user->getRoles());
$this->get('security.token_storage')->setToken($token);
BUT also take a look at symfony's impersonalizaiton => https://symfony.com/doc/current/security/impersonating_user.html
It basically allows you to switch users without filling out forms and knowing users' credentials

Custom Commands for FOSUserBundle are
fos:user:activate
fos:user:change-password
fos:user:create
fos:user:deactivate
fos:user:demote
fos:user:promote
There is no such way to authorize directly as you want it.
You can create a custom command in symfony which accepts username and authenticates a user. Here is a way to create such a command : https://symfony.com/doc/current/console.html

Thanks you, guys! I found the solution here!
How to programmatically login/authenticate a user?
Sorry for wrong or stupid question.

Related

FosUserBundle don't send email to resset password

I have a simple form to login and reminder password, I overwrite the FOSUser template and everything works fine, but when I want to email the password reminder I do not get it to the mail.
This looks like a swiftmailer and fos configuration in config.yml:
swiftmailer:
transport: '%mailer_transport%'
host: '%mailer_host%'
username: '%mailer_user%'
password: '%mailer_password%'
spool: { type: memory }
fos_user:
db_driver: orm
firewall_name: main
user_class: AirblogBundle\Entity\User
from_email:
address: "admin#admin.com"
sender_name: "Admin"
resetting:
email:
from_email:
address: noreply#yoursite.com
sender_name: No Reply
token_ttl: 0
After sending the email from the resetting/request path, I get the following information:
An email has been sent to ...#wp.pl. It contains a link you must click to reset your password.
Which seems correct because the address entered in the form has the same ending, but my mailbox does not receive any message.
ps: One more question, how to simply overwrite the Twig template, so the login and reminder of the hymn was on one page? Do you need to overwrite the controller?
Did you configure the needed parameters of SwiftMailerBundle well ?
First of all I suggest you to use Symfony's command to check your swift mailer configuration.
Specify the good arguments to send you a debug mail with reading the help command
php app/console swiftmailer:email:send --help
You should receive a mail on the email address you wrote in command.
After this step you can assume that your mail configuration is good
Reset your forget password request
One important (in the version installed on my project, composer requirement ~2.0) thing to know that is FOSUserBundle don't resend mail if you didn't click on the previous reset link sended BUT he display to you the message that he sended the mail.
If you want to "reset" your password request for a specific user
UPDATE user SET confirmation_token = NULL, password_requested_at = NULL WHERE username = "yourdebugusername"
Extending FOSUserBundle Twig templates
You should read this documentation
Basically you can override all the FOSUserTemplate under vendor/friendsofsymfony/user-bundle/Resources/views
I hope it's help !
For overriding FOSUser twig template looks the Symfony Doc

Define roles in a bundle config

I have some questions about roles that I'm trying to understand a long time:
1. We have some bundles that we use in couple of projects. We would like to define roles in a bundle config, so that we do not copy roles into the role_hierarchy in security.yml. Is there any clean way to do it?
My first idea was to import them into role_hierarchy like this:
role_hierarchy:
ROLE_ADMIN: ROLE_USER, ROLE_TRANSLATOR
ROLE_SUPER_ADMIN: ROLE_ADMIN
ROLE_NOT_APPROVED_USER: ROLE_USER
ROLE_TRANSLATOR: ROLE_USER
"%base_bundle.role.hierarchy%"
This of course doesn't work. Is there any possibility to do it this way(merge arrays in yaml)?
My other idea was to store roles in DB, but in my opinion it's overkill, because we have no dynamic roles. Everything is static.
Is there any workaround to achieve what I try to do? Or is it a good idea to define it in a bundle?
2. I use roles as permissions (ROLE_POST_EDIT, ROLE_POST_DELETE, ...) and voters to deny or approve access to the resource. So at the end there are a tons of roles. Is it a good idea to mix roles with permissions? If not what is the best practise?
EDIT: I feel the difference between ROLE_POST_EDIT and ROLE_USER or ROLE_ADMIN. User has ROLE_USER because he is user. But user has "permission ROLE_EDIT_POST" to be able to edit a post. In my opinion there is a difference between. Anyway should I care about this difference or is there any other practise how to do?
We have some bundles that we use in couple of projects. We would like to define roles in a bundle config, so that we do not copy roles into the role_hierarchy in security.yml. Is there any clean way to do it?
You can use Prepended Extensions to "prepend" configuration of another extension:
class AcmeHelloExtension extends Extension implements PrependExtensionInterface
{
// ...
public function prepend(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
'ROLE_ADMIN' => ...
...
],
]);
}
}
I use roles as permissions (ROLE_POST_EDIT, ROLE_POST_DELETE, ...) and voters to deny or approve access to the resource. So at the end there are a tons of roles. Is it a good idea to mix roles with permissions? If not what is the best practise?
A small misconfusion here: The roles you define with role_hierarchy are not related to the things you pass to isGranted(). You're passing attributes to isGranted(). Unfortunately, for the RoleHierarchyVoter, symfony decided to make the attributes similair to the role name (that is, if the role name starts with ROLE_).
Voters vote on permissions, or attributes as they are called. So it's perfectly valid and good practice to have many permissions in isGranted().
However, I recommend not to start them with ROLE_*. These attributes are checked by the RoleVoter/RoleHierarchyVoter. Name them e.g. POST_EDIT, POST_DELETE:
if ($this->isGranted('POST_EDIT', $post)) {
// ...
}

Symfony 2.8+ LDAP Roles

I have set up the new LDAP system with symfony 2.8+
LDAP but I have a problem with the role. It is stated in the documentation that
# app/config/security.yml
security:
# ...
providers:
app_users:
ldap:
service: app.ldap
base_dn: dc=example,dc=com
search_dn: CN=My User,OU=Users,DC=example,DC=com
search_password: p455w0rd
filter: (sAMAccountName={username})
**default_roles: ROLE_USER**
But I don't know, how it works. I would like to get the user from my LDAP and then give them roles. Is it possible with the new LDAP Sytem within symfony ?
I previously used IMAG/LdapBundle but you can't set your own roles because of a bug never patched which prevent modifications from beiing saved...
It currently is not really possible in the Symfony LDAP component (as of the most current, 3.1). See this open issue.
However, I maintain a bundle that allows this as you can define roles that map to specific LDAP groups: https://github.com/ldaptools/ldaptools-bundle. Dunno if that will help you, but I tried to give it a lot of different configuration options.

Change role of one user no working with Symfony2

Sorry if this question has been asked many times but I didn't found any solution on the Web.
So, I just have installed FOSUserBundle and I've created 2 users on my application with the console. The problem is they don't have any role.
So in on controller, I get the user Entity and y set his role but when I try to access to a page restricted for admin, it says access denied. Moreover, the roles has no changed on the databse.
My code in the controller :
$user = $this->container->get('security.context')->getToken()->getUser();
$user->setRoles('ROLE_ADMIN');
if (!$this->get('security.context')->isGranted('ROLE_ADMIN')){
throw new AccessDniedException('Access Denied !');
}
Anyone have an idea ?
Thanks in advance !
It is a very bad practice to set a user role in your controller if you want to keep them away from the controller in the first place. I hope you use this line of code for testing only.
The FOSUserBundle provides a number of command line utilities to help manage your application's users.
The one you need is:
$ php app/console fos:user:promote testuser ROLE_ADMIN
Replace testuser with your username.
Did you also define your roles in your firewall?

Switch roles FOSUserBundle

I am using FOSUserBundle for handling my users. For them I have 2 roles ROLE_CUSTOMER and ROLE_MANUFACTURER. The problem is that I need to be able switch these roles when I am logged in. Is it possible? I have read this documentation:
http://symfony.com/doc/current/cookbook/security/impersonating_user.html
There is said how I can switch user to other user without relog, but nothing about role switching.
Maybe someone has any code examples or something? I have read too lot documentations which are hard to understand.
Look at my answer here - Symfony 2.3: How do I refresh the authenticated user from the database?
The key is you need to reset a token after you switched roles.
Something like this:
$loggedInUser = $this->get('security.context')->getToken()->getUser();
$loggedInUser->removeRole('ROLE_ABC');
$loggedInUser->addRole('ROLE_XYZ');
$token = new \Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken(
$loggedInUser,
null,
'main',
$loggedInUser->getRoles()
);
$this->container->get('security.context')->setToken($token);

Resources