I'm loading a user to get his roles, but I only get the role machine name, I found the way to load those roles:
$roles = Role::loadMultiple($user->getRoles());
but now I need to get the labels of those roles.
Thanks.
foreach ($roles as $role) {
$label = $role->label();
}
Related
I’m developing a REST API using NestJS and Prisma. The RBAC is done using an enum with a role guard.
I would like to use the same controller method for different user roles and return specific fields only for specific roles.
What’s the best way to do this?
Like ADMIN role should return all fields while USER role should only return certain fields.
Thanks.
If it's possible in your case, you can describe your select opition in prisma request based on RBAC
const getUser: object | null = await prisma.user.findUnique({
where: {
id: 22,
},
select: {
email: role === Role.Admin, // <== like this
name: [Role.Admin, Role.User].includes(role), // <== or like this with multiple roles
},
})
I have a LDAP connection set up in my Keycloak. I've managed to import the normal LDAP roles into keycloak with a mapper. In our LDAP we have roles also mapped as user attributes, so like cn, sn, c ... we have attributeRoles. Of course these are not really roles from the technical point of view but user attributes(They are used in our application as roles).
What I want to achieve is to map these user attribute roles(attributeRoles) to real roles in keycloak.
Did any of you have this specific problem and managed to solve it somehow?
Any help would be appreciated.
Update the onImportUserFromLDAP in the RoleLDAPStorageMapper with the following code:
Map<String, Set<String>> attributes = ldapUser.getAttributes();
for (Map.Entry<String, Set<String>> entry : attributes.entrySet()){
if(entry.getKey().equals(<ATTRIBUTE>)){
// Try to import the attribute to Keycloak roles
importAttributesFunction(user, realm, entry.getValue());
}
}
and here you have the importAttributesFunction:
public void importAttributesFunction(UserModel user, RealmModel realm, Set<String> sRoles) {
for(String sRole: sRoles){
RoleContainerModel roleContainer = getTargetRoleContainer(realm);
RoleModel role = roleContainer.getRole(sRole);
if (role == null) {
role = roleContainer.addRole(sRole);
}
if(!user.hasRole(role)) {
user.grantRole(role);
}
}
}
Hope it helps.
Assume i have the following Role based authorization for an action
[AuthorizeDBRoleAttribute(Roles = "Manager")]
public ActionResult Welcome()
{
return View();
}
here is the AuthorizeDBRoleAttribute class
public class AuthorizeDBRoleAttribute : AuthorizeAttribute
{
public string Roles { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContextBase)
{
//Bind User Roles from Database here
string userRoles = "Manager,Supervisor,Inspector";
if (userRoles.IndexOf(Roles) > -1)
return true;
else
return false;
}
}
I have separate DB tables Roles and Users
Assume the current user logged in is of Role Manager. How does this "AuthorizeDBRoleAttribute" attribute knows the current user's role so it can let access to the Action method
How to setup Role based authorization was discussed in this post. I want to drag it a bit further in to the next step on how MVC figure out the current user's role etc
You start with current IPrincipal, taken from the http context and set there by the authentication module.
Then, depending on your current approach (which we obviously don't know) you either have roles already stored in the principal object or you have only the user name and you retrieve roles from the database for the current user name.
The author of the code you cite even put a comment there - retrieve user roles for the current user name, more or less something like:
string username = httpContextBase.User.Identity.Name;
var roles = whereeverYourRolesAreStored.RolesForUser( username );
We have used RBAC to implement simple role based permissions for CRUD, but now we need to also add a 'visibility' functionality which makes it possible to limit content visibility (R) to only registered users or only the content owners.
So, how can we limit content visibility on different levels, for example
PUBLIC: anybody can see the content, including anonymous
INTERNAL: only registered users can see the content
PRIVATE: only the creator can see the content
What would be the best way to implement this, it looks like RBAC does not have a straightforward way of dealing with this.
I think that the problem can be solved by using defaultScope in models. Thus, before giving the content, we can check the current role of the user data and give the necessary conditions.
public static function find()
{
$userRoleArray = \Yii::$app->authManager->getRolesByUser(Yii::$app->user->getId());
$userRole = current($userRoleArray)->name;
if ($userRole == 'admin') {
return parent::find()->where("Your condition");
} elseif ($userRole == 'moderator') {
return parent::find()->where("Your condition");
}
}
you can make a permission function and run in each function that will take user role as argument and returns true or redirect to not allowed page.
Here is something I tried but you can modify according to your need.
public function allowUser($min_level) {
//-1 no login required 0..3: admin level
$userRole = //get user role;
$current_level = -1;
if (Yii::$app->user->isGuest)
$current_level = 0;
else
$current_level = userRole;
if ($min_level > $current_level) {
$this->redirect(array("/pages/not-allowed"),true);
}
}
I have login form with input text fields:
Group Name
User Name
User Password
I have two tables
groups
id
name
users
id
name
group_id
I have its mapping entities and associations.
But user name not unique within table users, because different groups can include users with equal names. Therefore i need:
find group by name in table groups
find user by name in table users with condition where group_id=<group_id>
How to do it correctly in Zend Framework 2 using Doctrine 2?
All official documentation and examples depict situation, where identity property is single column (example).
Sorry for my bad language. Thanks.
Instead of making my own implementation of Doctrine's authentication services i decide to implement it via form validation inside isValid() method of my authentication form.
Example:
<?php
namespace My\Form\Namespace;
use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\InputFilter\InputFilterProviderInterface;
class Auth extends Form implement InputFilterProviderInterface
{
protected $_em;
public function __construct(ServiceLocatorInterface $sm)
{
parent::__construct('auth');
// inject Doctrine's Entity Manager
$this->_em = $sm->get('Doctrine\ORM\EntityManager');
// login field
$this->add(...);
// password field
$this->add(...);
// group_name field
$this->add(...);
}
public function getInputFilterSpecification()
{
//Input filter specification here
...
}
public function isValid()
{
/*
* input filter validations
*/
if (!parent::isValid())
return false;
/*
* group exists validation
*/
$group = $this->_em
->getRepository('<Group\Entity\Namespace>')
->findOneBy(array(
'name' => $this->get('group_name')->getValue(),
));
if (!$group){
$this->get('group_name')
->setMessages(array(
'Group not found',
));
return false;
}
/*
* user exists validation
*/
$user = $this->_em
->getRepository('<User\Entity\Namespace>')
->findOneBy(array(
'group_id' => $group->getId(),
'name' => $this->get('login')->getValue(),
));
if (!$user){
/*
* It's not good idea to tell that user not found,
* so let it be password error
*/
$this->get('password')
->setMessages(array(
'Login or password wrong',
));
return false;
}
/*
* password validation
*/
$password = $this->get('password')->getValue();
// assume that password hash just md5 of password string
if (md5($password) !== $user->getPassword()){
$this->get('password')
->setMessages(array(
'Login or password wrong',
));
return false;
}
return true;
}
}
Inside controller it is enough to call $form->isValid() to make sure that user entered correct authentication data.
I have the same problem.
I have to do two authentications in same application, because my boss doesn't wanna two databases. So, I had to make two user tables and two login pages.
One route to admin -> /admin/login
And the front-end for other users -> /login
I've tried to put on more authenticate in doctrine authentication array but it didn't work.
I think I'll open a issue on doctrine github page.