Determine all groups for a defined user - xpages

I am currently creating a java method(part of and XPages managed bean) to retrieve a list groups a user(not necessarly current user) is a member of.
Is there any easy method to retieve this information or am i going to have to loop through all the groups to check for the user and also check if those groups are sub groups of other groups?

Answered this in a blog post here: http://ntf.gbs.com/nathan/escape.nsf/d6plinks/NTFN-8TMHRP
Simple version is that what you're looking for is...
lotus.notes.addins.DominoServer server = new lotus.notes.addins.DominoServer("YourCanonicalServerName");
Collection nameList = server.getNamesList("TheUserNameYou'reLookingFor");
That should be all you need.

use this snippets:
XSPContext context = XSPContext.getXSPContext(FacesContext.getCurrentInstance());
DirectoryUser currentUser = context.getUser();
Vector<String> groups = new Vector(currentUser.getGroups());

You can retrieve this information from ($ServerAccess) view in names.nsf, which is categorized by user name.

session.evaluate( "#UserNamesList" );

Rather than looping through all the groups in all the directories on the server you might prefer to create a special view in each director organized by group members. That makes the finding of matches quite a lot faster.
The GroupManager tools mentioned by Jasper are also a good example of LotusScript code which accomplishes most of what you want. The objects in Java are the same, the syntax is just a lot more pesky.
/Newbs

Not sure if you can (re)use the LotusScript here, but this article (IBM DeveloperWorks, look at the 4th paragraph) is a great start. It mentions the NotesGroupManager and NotesGroup classes. These classes could be used as a basis for rewriting the code for XPages. There seems to be no other "easy" way to find all the groups a user belongs to. The straight answer to the question seems to be NO.

Related

Use ACL isGranted inside a voter isGranted

Edit: See my answer below.
For my needs, I decided to use both ACL and voters for my app (maybe it is not the best way, please, tell me if I'm wrong with this).
My entities represent a factory where there are :
Lines owning Workshops owning Equipments owning Spare Parts.
I want to give either a manager or a viewer access to a line level. For this purpose, I use an ACL on the line.
Because there are more than 5000 spare parts per line, I don't want to write 5000 ace to tell symfony that this user, which is allowed to manage this line, can manage the spare parts of the line.
To solve this problem, I decided to add a voter before the acl check.
I do a isGranted('edit',$sparepart) which is handled by a voter, and inside my own voter, I want to perform a isGranted('OPERATOR',$line).
Actually, I have many more things to check (is the user plant manager ? for example) and I like to combine the voter and the ACL.
Unfortunately, I'm a bit lost and I don't manage to call the right "isGranted" from my voter, I get an infinite loop error.
Voter isGranted
$authChecker = $this->get('security.authorization_checker');
$authChecker->isGranted('', $post);
ACL isGranted
$securityContext = $this->get('security.context');
$securityContext->isGranted('EDIT', $comment);
I understand this might be a bit confusing, and maybe I'm not doing it the right way :s
Thanks for your help !
So I finally did this in another way.
I use one voter and I created new entities to manage my access.
I have a LineAccess entity with:
ManyToOne: Line
ManyToOne: User
Sp_access: smallint
Cart_access: smallint
Line_access: smallint
So I check everything by myself and I also manage the links with my LineAccess entity and CustomerAccess entity.
Finally, it is the best way I think. Good luck
Here is the full problem for the curious :
For each user, I want to be able to select his permissions with this table.
If, for example, I check Boeing (the customer) manage. I will create an ACL/ACE with OPERATOR for this $customer.
That's it. Later, I want to check if this user is able to manage a line by first looking at a 'OPERATOR' on $line but if it doesn't exist, I will check 'OPERATOR' on $plant, and then 'OPERATOR' on $customer.
If I select Manage Dreamliner plant, I get this :
You can see that I'm still able to chose the kind of access to spare parts and cart. I can set this user, which is a plant manager, another permission : Spare parts manage. For that kind of permission, I can use the mask builder feature which allows me to store with a single integer "SP_MANAGER, CART_VALIDATE, LINE MANAGE', for example.
You can see that it gets a little complex here and this is why I think that ACL are my best friends, but I wanted to add a level of control in which I can manually select which isGranted() method, and on which entity.
I tried to be precise but it is not that easy :s
Thanks a lot for your help !
Voters and ACL are both standalone architecture approach to authorization. I'd recommend using Voters only, since they're easier to understand, use and extend.
For more details on this comparison, check these explanatory slides.
Where exactly you can't use Voters instead of ACL?
Also, why you need to nest Voters/ACL?
Thanks for your quick answer !
Actually, I thought I needed ACL because I have to put in the database my permissions. And here is the kind of permissions I want :
User A:
Manage line 1 (include workshops, equipments, sp) and can create shopping carts in this line.
View line 2 (can't manage the line but can see it's content) and can only validate the shopping carts.
So I thought it was good to use ACL because that way I can write in the database the permissions for each objects.
I also like the fact that I can use masks.
(There is the same logic on the Plant level)

How can i provide role based security to notes in MS CRM 2011

I am working on Notes in MS CRM 2011.
I have many roles over many entities.
I want role based security to notes for any entity records.
let me explain what i want:
Suppose i have an entity namely E1.
Role R1 and R2 has read and write access to E1.
But i want that user having role R2 can only upload and view notes for any record of entity E1.
Hope now my requirement is clear to all of you.
Please suggest me how can i achieve it using MS CRM 2011.
I can think of two ways to do this.
You can create a plugin on create/update of the annotation(note) and check if the note is related to entity E1 and check the roles of the user making the change and see if they only have the R2 role. If that is the case you can throw an InvalidPluginExecutionException with a message like 'You do not have permissions to edit/create these records'.
You can try using role based forms or JS to hide the notes area for R1 users.
You probably want to use a combination of #1 & #2. The users can still access the notes via advanced find and thus will be able to edit those notes. The plugin will prevent that fringe case as well.
*Edit
There are a couple more things that you might be able to deal with the advanced find records. You can remove the annotation entity from advanced find via the unsupported method described here.
Otherwise there is one more thing you can do if you want to prevent those results showing up at all, and you want to stay supported. You can write a plugin on Post-RetrieveMultiple of the annotation entity to strip out the results directly from the return result. There are a couple downsides to this though.
You are executing your plug-in every time the retrieve multiple is called on the entity. So this code will need to be as efficient as possible since that delay will be noticeable by the end user whenever they retrieve these records.
Things like advanced find will display odd results. For example if your paging is set to 50 records and you strip out 10, they will only see 40 records on their page and the total record count will include the records you are stripping out.
Through roles i don't know a way to do that, because you configure the access to notes generic, so applies to all entities. You have to access with Javascript navigating in DOM. Check a example:
document.getElementById("notescontrol").contentWindow.document.getElementById("NotesTable")
You can check this with the help of a develeper tool in your browser.

Orchard CMS - Grouping fields

Is there a possibility to have fields that are added to a contentpart to be grouped. I don't know upfront what fields the customer will add. And if he adds a lot of fields to the contentpart, it would be nice if there was some kind of identifier to group them.
Should I take over the Orchard.Fields module and modify it or is there an easier way?
There is no easy way to do that today, but this is such a common request that I think it should be submitted as a work item (or even better, a patch) on CodePlex. We should add a group attribute to fields and maybe even parts.
UPDATE: I created it for you: http://orchard.codeplex.com/workitem/18920 Feel free to vote for it.

Sharepoint alerts not working when multiple people are in an item

We use Sharepoint Services 3.0 as a project tracking tool. We have a list set up that contains your basic information (description, etc.) plus we have a "assigned person" column that is of type Person or Group that we use to associate list items with individuals. This column supports multiple selections.
We would like to set up alerts such that each person gets an alert email only if they are assigned to a list item. The approach we have taken is to set up a view on this list that is filtered to show list items where the assigned person equals [Me], and then to create an alert on this list that is set to send an email when someone changes an items that appears in the view.
This works well when there is only one person in the assigned person column. It does not work when there is more than one person in the assigned person column.
Does anybody know why this wouldn't work, or what I can do to troubleshoot? Is there a better way to achieve the end result? We could make several "assigned person" columns and not allow multiple selections, but that seems kind of kludgy.
Try this info site,
http://www.sharepointalert.info
it has a good alert trouble shooting guide.
The reason it works for one person but not multiple people is because the check is specifically against an individual. The comparison your view does is whether Assigned is equal to [Me], not if Assigned has [Me] as one of its entities.
Instead of using a list filter of is equal to, use the list filter contains. That should do the trick.
EDIT IN RESPONSE TO COMMENTS
To access the object model, you'll need to use Visual Studio. I'm unaware of a method to accomplish this kind of thing using SharePoint Designer, but maybe there's some sort of crazy Datasheet View thing you can do. Anyway... onto your actual needs...
The following code sample illustrates a very basic method for achieving your goal.
using (SPSite site = new SPSite("yourwebsiteurlhere"))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists["titleoflist"];
SPView view = list.Views["filteredviewname"];
view.Query = "<Where><Contains><FieldRef Name=\"assignfield\"/><Value Type=\"Integer\"><UserID Type=\"Integer\" /></Value></Contains></Where>";
view.Update();
}
}
Replace "yourwebsiteurlhere" with the website url, "titleoflist" with the title of your list in question, "filteredviewname" with the name of the view, and "assignfield" with the internal name that you used for your assignment field. If you created it through the standard SharePoint UI, this should be the name of the field without any spaces.
As far as where to run the code, you could put this kind of thing in a one-time workflow. I sometimes do that just to make sure I have necessary privileges. Hope this helps!
If you're not able to/allowed to use Visual Studio, then your solution will probably have to be to look into a 3rd party solution.

Problem finding Item List Id in WSS 3.0

I'm having a hard time figuring out how to refer to a specific Item List within a list in SharePoint. I looked up the page in SharePoint Designer and found that the listitem is inside a custom made webpart inside a custom made webpage. I'm coding an event receiver and need to read the information that the user types into that listitem which is a textbox. Does anyone know the code to do this or how to get the guid for the specific list item?
I would appreciate any help I can get. I have tried looking all over the web for the answer. Thanks.
It might be a good idea to edit your question with exactly what you'd like to do with the information you read. However from what you've said so far:
The ID of the item being edited will already be passed through to the event receiver via SPItemEventProperties so there is no need to look it up. If you need to look up a different item in the list (or indeed in a different list altogether), the Accessing list items using the object model page on SharePoint Dev Wiki gives you all of the options. A good general rule is use SPQuery to get best performance on the whole.
Note: There is a pretty good page on the SharePoint Dev Wiki demonstrating how to write an event receiver. It shows how to query and obtain a list item title.
Update after comments:
Once you have an SPListItem object, you can find its GUID through the UniqueId property. In the "Accessing lists" wiki link I've provided above the code samples show how to use the Title property.
Every piece of data you need to access within SharePoint should be available through the object model. This is a simplification, but generally the pages themselves are rendered from template files on the server and combined with data in the database to display to the user. So editing the page programmatically or through its source isn't going to work.
Apologies if I'm making an incorrect assumption but you sound fairly new to SharePoint development. I strongly recommend you read at least the first few chapters of Inside Windows SharePoint Services 3.0 as the inner workings of SharePoint are important to get a good understanding of and this book should help a lot. There is a section of event receivers in it as well.
Have you looked at SharePoint.ListsService Webservice?
string url = "WSS Site URL";
SharePoint.ListsService.Lists lists = SharePoint.ListsService.Lists(url);
XmlNode list = lists.GetList("ListName");
XmlNode xlists = lists.GetListCollection();

Resources