for an project we are using the liferay and for the user handling we are using the ldap.
The user when deleted from the ldap is not updating the database of the liferay and hence if a user to be added after deleting it, it is causing the problem.
I tried to found out the cause and seems like one has to delete the users from many tables. Manually we can delete it like mentioned below.
DELETE FROM Users_UserGroups WHERE userId = 'userid';
DELETE FROM Users_Roles WHERE userId = 'userid';
DELETE FROM Users_Orgs WHERE userId = 'userid';
DELETE FROM Contact_ WHERE userId = 'userid';
DELETE FROM Group_ WHERE classPK = 'userid';
DELETE FROM User_ WHERE userId = 'userid';
but programatically how can we do that.
I tried using:
UserLocalServiceUtil.deleteUser(UserLocalServiceUtil
.getUserByEmailAddress(companyid, email));
But its not working properly. what are the other ways to do that?
Despite my comment "please define it's not working properly", I'd like to give an answer that shows up an alternative. Instead of giving you the solution to the words of your question, this will address the underlying problem. If you need an actual answer to the words of your question, please describe what you're observing.
Deleting a user is a dangerous operation: You might leave dangling references, e.g. if that user has participated in some activities in a portlet. They might be authors of blog posts, content articles or message board messages. And this is not an exhaustive list.
Therefor it's always better to just deactivate a user - this way their name, portrait image and other data is always available even long after they're allowed to log in.
Get the email of the users that you want to delete from the User_ table . And insert it in ArrayList .
In my case i have placed this code in a sample program and run this code once.
`
List<User> users = UserLocalServiceUtil.getUsers(QueryUtil.ALL_POS, QueryUtil.ALL_POS);
ArrayList<String> places = new ArrayList<String>(Arrays.asList("a#vc.com","abc#abc.com"));
for (User user : users) {
if (places.contains(user.getEmailAddress())) {
System.out.println("user "+user.getEmailAddress()+" deleted");
UserLocalServiceUtil.deleteUser(user);
}
}
`
Hope this helps!!
Related
So basically I am trying to make a ticket sort of discord bot using discord.js.
The concept: someone says +help then it DMs a member, who has said +onduty and has a role of something like "Helper".
I need to work out how to detect the role and add them to a set who are "on duty".
I was wondering if anyone can help me with this.
Many thanks.
The way I do stuff like this in my bot (snipet from my example bot's kick command):
// This command should be limited to staff. In this example we just hardcode the role names.
// Please read up on Array.some() to understand this bit:
// https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some
if(!message.member.roles.some(r=>["STAFF","Helper"].includes(r.name))) {
return message.reply("Sorry, you don't have permissions to use this!");
}
A little bit of the documentation on this:
https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=member
https://discord.js.org/#/docs/main/stable/class/GuildMember?scrollTo=roles
message.member.roles contains a collection of the members roles
we can use .some() to go through them and see if the user has a role
.some(): https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some
So to go through all guild members to see if they have helper then, if they also have on duty:
// assuming the Message is in a variable called message
var gm=Array.from(message.guild.members);
for(var member in gm) {
if(gm[member].roles.some(r=>["Helper"].includes(r.name))) {
if(gm[member].roles.some(r=>["on duty"].includes(r.name))) {
gm[member].send(`Help command ran:\nUser: ${message.author.tag}\nContent: ${message.content.replace("+help ","")}`);
}
}
}
if a user runs the command +help <what they need help with> it will send to someone in the guild with the roles helper and on duty:
(using my Discord tag for an example)
What was ran: +help I need some help with something
"Help command ran:
User: Donovan_DMC#1337
Content: I need some help with something"
(without quotes)
as for this
I need to work out how to detect the role and add them to a set who are "on duty".
I assume you mean that when someone with the role helper runs the command +onduty they get the role on duty.
var roleid=message.guild.roles.find("name","on duty").id;
if(message.member.roles.some(r=>["Helper"].includes(r.name))) {
message.member.addRole(roleid);
}
A few documentation links to hopefully help you understand this
message: https://discord.js.org/#/docs/main/stable/class/Message
message.guild: https://discord.js.org/#/docs/main/stable/class/Message?scrollTo=guild
message.guild.roles: https://discord.js.org/#/docs/main/stable/class/Guild?scrollTo=roles
and for removing the role it's almost exactly the same
var roleid=message.guild.roles.find("name","on duty").id;
if(message.member.roles.some(r=>["Helper"].includes(r.name))) {
message.member.removeRole(roleid);
}
In summary a basic bot for this you could have something like this.
^ I've added some extra checks for already having the role, not having it, and made it where the prefix can be changed
I've tested it, and it worked wonderfully.
I'm following a tutorial about firestore but I don't understand firestore rules very well. I'm trying to allow anyone to be able to create in the standard
users/uid/
path but only allow updates if the requester is trying to update
users/theirUserId/
I saw this in the documentation, but it didn't seem to work for me:
allow write: if request.auth.uid == resource.data.author_id;
Can anyone explain the functionality of the above line and/or offer suggestions as to how I can achieve this?
Additionally, is there any way to specify rules for a specific piece of data within a document?
It looks like that your document doesn't contain a author_id field.
The Firebase documentation Writing Conditions for Security Rules use this example:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches the 'author_id' field
// of the document
match /users/{user} {
allow read, write: if request.auth.uid == resource.data.author_id;
}
}
}
It means that a random user will be able to read and write in the users collections only if their authentication ID equals the author_id field of a specific document.
The resource variable refers to the requested document, and resource.data is a map of all of the fields and values stored in the document. For more information on the resource variable, see the reference documentation.
For your second question, I recommend you to have a look on the documentation about resource variable (link in the quote above). It is the same logic as your author_id question.
You can split allow write in to three create, update, delete for specific cases.
In your case
allow create: if request.auth.uid != null;
allow update: if request.auth.uid == resource.data.author_id;
which says any authenticated users can create and only update their on document. and created user must have a field author_id which is their user id.
Why do I want this?
I'm trying to get a unique identifier from my user which I can connect to database records. There are reasons I don't want to use the Email as the identifier. I read that SUB claim isn't supported with B2C, and to use OID in it's place.
Steps I've Taken
So, I've set up that both of my policies return Object ID on Azure B2C:
I'm using individual SignIn and SignUp policies at the moment, and I get all of the claims back, including the email claim which I specified I wanted to be returned. I cannot however find a claim related to OID or SUB.
User.Claims
Nets me the following results:
The single breadcrumb of hope that I have found is this claim:
Type: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier
Value: Not supported currently. Use oid claim.
Questions
Have I missed some additional step that you need to perform to retrieve this particular claim?
Has anyone had any success retrieving an OID or SUB from Azure B2C?
Well, this is embarrassing, I must have looked over this line about 30 times and not noticed...
I was retrieving the OID token, it's claim type was:
http://schemas.microsoft.com/identity/claims/objectidentifier
As can be clearly seen in my provided screenshots. I'll leave this question up as, the schema may throw someone else off.
I struggled with this for a little while and this post helped me.
To update things with some code, the below will obtain the object identifier value (unique user id in Azure)
User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value
Thanks for pointing out the differences in the schema/types!
If you are using the Microsoft.Identity.Web package there is now a ClaimsPrincipalExtensions class that provides an extension method, so that you can simply use:
// using Microsoft.Identity.Web;
User.GetObjectId();
This uses the oid or http://schemas.microsoft.com/identity/claims/objectidentifier claim.
Since the links above are broken and this is something that I really struggled to find a working example of, here is a code fragment of what I ended up using;
using System.IdentityModel.Tokens.Jwt;
...
string oid;
string pTokenInput = Request.Headers["x-ms-token-aad-id-token"].ToString();
var lJWTHandler = new JwtSecurityTokenHandler();
if (lJWTHandler.CanReadToken(pTokenInput)
{
var lToken = lJWTHandler.ReadJwtToken(pTokenInput);
if (lToken.Payload.ContainsKey("oid"))
oid = lToken.Payload["oid"].ToString();
}
Hopefully, this will help someone else...
It seems that you do not necessarily need object-identifier here.
When debugging, I see that the value of object-identifier is mapped to nameidentifier
Which is accessible with the built-in constant NameIdentifier:
var identity = authState.User.Identity as System.Security.Claims.ClaimsIdentity;
var userId = identity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier).Value;
I have a site where user A can book a lesson with a teacher, I then want to have an email sent to the teachers saying user A wants to book a lesson with you etc.
I have postal up and running sending emails without issue,
however, I don't know how to access the email address of the teacher to send the email.
The email address is saved as part of the built in UserProfile table. I have the teacher's UserId (as it's stored in a separate teacher table).
So is there a way to access the teachers email ,searching by UserId?
In any other table I would use t in db.Teacher.find(id) but this doesn't work within the Account Controller.
This was built using the default MVC4 internet website template using the built in simple membership. Let me know if more information is needed.
I've added the following to the AccountController;
private UsersContext db = new UsersContext();
public ActionResult EmailNotification(int id)
{
var user = from l in db.UserProfiles.Find(id)
select l;
}
db.UserProfiles.Find(id) however gives the following error;
Could not find an implementation of the query pattern for source type 'LessonUp.Models.UserProfile'. 'Select' not found.
Which I assume is a result of it not being created through the entity framework?
I think your query needs to be something like the following:
var result = from q in context.UserProfiles
where q.UserId == id
select q;
I have a question about the rbac system. I think I've pretty well understood it but I need more informations about a special case.
I would like to do the autorisations on groups instead of users. I mean for instance the group "HR" has permission to create a person. Then any person who join this group would have it as well.
Let me give you more informations.
A part of my database:
And this a part of what my group hierarchy could be:
So what I'm looking for, this would be a must, is a system where each group has some autorizations. People get the autorizations of their group and of their parents group (for instance people in "Forsys" has the autorizations of "Forsys", "R&D" and "Administration").
The solution I see at the moment is using bizrule. But I'm not sure write php code in database is a good idea and then if I update the group hierarchy (R&D inherits of RH instead of Administration) I would have to modify bizrule in database. I tried it and it works well but as you can see it require a lot of code.
$user = User::model()->with("people","people.groups")->findByPk(Yii::app()->user->id);
foreach($user->people[0]->groups as $group)
if($group->id == 2)
return true;
return false;
It's just for see if a user is in a group (without checking parent groups and hierarchy)
Another possibility could be create a new table "group_auth" where we would say for instance:
-Group_2 has role "managePerson"
-Group_3 has operation "deleteUser"
...
And then everytime a user is added in or removed of a group we would update his autorizations in the auth_assigment table.
I'd like to hear other opinions on this subject.
All comments will be appreciated :)
Thank you for reading and sorry for my English if you had difficulties to understand me.
Michaƫl S.
Do users ever get their own authorization items? If not, seems like you could in essence swap out the userid column in auth_assignment and name it / treat it as groupID instead. That way you wouldn't need to worry about keeping user auth assignments in sync with your group roles.
A couple of places you'd probably need to make some changes:
- by default CWebUser passes in the logged in userid for use in bizrules. Might be good to change that our with your own override that passes in groupId/groupIds instead.
- you'd need to override CDbAuthManager and rework some of how things work there
We've done something similar on a project I've worked on (we were handling multi-tenant RBAC custom permissions), which required custom CDbAuthManager overrides. It gets a bit tricky if you do it, but there is an awful lot of power available to you.
Edit:
Understood about your users sometimes needing to have additional authorizations. What if your group has a 'roles' field with different roles serialized in it (or some other method of having multiple roles stored for that group, could also be a relationship).
Then, on user login (for efficiency), you'd store those roles in session. Probably the easiest way to handle things would be to write a custom checkAccess for your WebUser override:
https://github.com/yiisoft/yii/blob/1.1.13/framework/web/auth/CWebUser.php#L801
as that will make things simpler to do your custom checking. Then I'd probably do something like:
if(Yii::app()->user->hasGroupAccess() || Yii::app()->user->checkAccess('operation/task/role')) {
....
}
In your WebUser hasGroupAccess method, you could loop over all group roles and send those to checkAccess as well.
Think that will work?
What I use to check access for groups when it's in another table, or somewhere else in the application I give the user the role per default. By using this:
return array(
'components'=>array(
'authManager'=>array(
'class'=>'CDbAuthManager',
'defaultRoles'=>array('authenticated', 'R&D', 'Administration'),
),
),
);
Under: Using Default Roles
By using this, every user gets these assignments. Now, I create a business rule to make sure that the checkAccess('group') will return the correct value.
For example in your case the business rule for R&D would be:
return (
count(
Person::model()->findByPk(Yii::app()->user->id)->groups(array('name'=>'R&D'))
) > 0
) ? true : false;
So what this does is:
find the logged-in person by primary key
look into groups (from the user) for the group with name R&D
if there is a group: return true (else return false)