how to set exclusive permissions on a SharePoint document library? - sharepoint

I have a requirement to lock down access to a SharePoint library: Only users that belong to all the groups associated with the library should have read access; others should not be allowed to read.
Let's say I have a document library that concerns three projects:
12345
13579
24680
I have users that belong to one or more projects:
Joe: 12345, 24680
Jane: 13579, 24680
Jim: 24680
Harry: 12345, 13579, 24680
I need to restrict access to this library to only users who belong to ALL projects. I.e., only Harry should have access; the others should be denied. We'd use SharePoint groups named after each project to represent the 'belongs' relationship.
Edited with more detail:
We plan to create the doc lib and set up the initial security via a workflow. However, more projects may be associated with the doclib after it's created, based on info entered in a form, and people can get moved in and out of project groups by admins (e.g. for promotions, new hires....)
For now, if a form submission adds a new project after inital setup, an admin will probably create a new group if necessary, and assign it access to the doclib. Eventually, we'd do this in a workflow.
Currently, we're writing code to assign the initial security state for the site:
We scan a list of projects entered by a user into a form, create new project groups if necessary, create a site and a couple of doclibs, break role inheritance and assign our groups read access to the doclib. We add some users to each project group.
At this point, any of those users have read access. What we don't know how to do is restrict access to only users who are members of all the groups.

You've made it hard on yourself.. SharePoint nor AD works this way, I'd go back to the drawing board because this will only cause pain ;)
I would decouple management of groups and their assignment to document libraries and sync rights throughout SharePoint like Koen mentioned.
e.g. you manage group membership separate from the groups you use to connect them to document libraries. Then you need a process to enumerate over these separate groups and assign the users in there to the document libraries individually according to your business rules. Brittle at best.

You could set your document library to BreakRoleInheritance and set permissions to your items individually.
This is a example:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite("http://..."))
{
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPRoleType role = SPRoleType.Reader;
SPRoleAssignment assignment =
new SPRoleAssignment(web.Groups["groupname"]);
assignment.RoleDefinitionBindings.Add(
web.RoleDefinitions.GetByType(role));
SPList list = web.Lists["name"];
SPListItemCollection items = list.GetItems(new SPQuery());
foreach (SPListItem item in items)
{
if (!item.HasUniqueRoleAssignments)
item.BreakRoleInheritance(false);
while (item.RoleAssignments.Count != 0) // remove all
item.RoleAssignments.Remove(
item.RoleAssignments.Count - 1);
item.RoleAssignments.Add(assignment);
}
}
}
});

The only way I can think of achieving this is to create a custom timer job that updates your document library every day by deleting all the rights, and then adding them again overnight. That would mean that people who join those projects will have to wait 1 day to get acces. You would just create a collection of all the users of group1, and check for each one if they exist in group 2, 3, ... and if they don't remove them from the collection.

Related

I am making the app in sharepoint, however i am not able to find the api in the sharepoint to resolve the issue

The API that I need from the sharePoint is mention below:-
How to get all groups a user is a member of
Inside library permissions we have a setting to disable library data from appearing in Search, Below mention is the screenshot for which I am looking the api.enter image description here
It depends on the chosen technology, but generally:
SPUser object have the Groups property.
In CSOM:
var ctx = new ClientContext(url);
var user = ctx.Site.RootWeb.EnsureUser(userName);
ctx.Load(user.Groups);
ctx.ExecuteQuery();
https://learn.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.spuser.groups?view=sharepoint-server#microsoft-sharepoint-spuser-groups
Use "NoCrawl" property from a SPList object.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.sharepoint.splist.nocrawl?view=sharepoint-server#microsoft-sharepoint-splist-nocrawl

Sharepoint Taxonomy Navigation

I am using taxonomy for building left navigation in the sharepoint site.
I am using below method for accessing the nodes.
NavigationTermSet navTermSet = TaxonomyNavigation.GetTermSetForWeb(SPContext.Current.Site.RootWeb, StandardNavigationProviderNames.CurrentNavigationTaxonomyProvider, true);
but its returning only two terms and not returning all the child terms under these 2 terms.
But if i logging to the site as admin i am able to get the all the child terms as well.
I tried with console appilcation and its working fine and its problem only with Annonymous user accessing the page.
I have given the Full Access to app pool account also.
Not sure what i am missing here, any lead will be really helpful.
Regards
CR
Try to use RunWithElevatedPrivileges to run with elevated rights.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(web.Site.ID))
{
// implementation details omitted
}
});

Symfony 2 - Sonata Admin Role based security

With Sonata, I'm trying to use the role based security.
I want to give a group, rights for listing, editing & creating users, so I created a role with
ROLE_MANAGE_USERS:
- ROLE_SONATA_USER_ADMIN_USER_EDIT
- ROLE_SONATA_USER_ADMIN_USER_LIST
- ROLE_SONATA_USER_ADMIN_USER_CREATE
This works fine, but according to the doc, I'm understanding that a user granted with
ROLE_SONATA_USER_STAFF
Should already inherit rights for [EDIT, LIST, CREATE], but that does not seem to be the case
I also tried with
ROLE_SONATA_USER_ADMIN_USER_STAFF
Is there something I misunderstood ?
I guess that's not the case. First of all, the name of the main roles for edit depends on the services names. For example, if the service of the admin is sonata.user.admin, then the roles will be, for example:
ROLE_SONATA_USER_ADMIN_LIST
ROLE_SONATA_USER_ADMIN_VIEW
As you can see, the prefix is always ROLE (symfony 2 requirement), followed by the service name (but having the dots exchanged with underscores, and all capital letters), and ended with the prefix for the specific permission:
LIST: view the list of objects
VIEW: view the detail of one object
CREATE: create a new object
EDIT: update an existing object
DELETE: delete an existing object
EXPORT: (for the native Sonata export links)
As I can understand, there is no ROLE_SONATA_USER_STAFF predefined for edit, list and create. However, you can define it in the hierarchy, in the security.yml file:
security:
role_hierarchy:
# Setting up
ROLE_SONATA_USER_STAFF:
- ROLE_SONATA_USER_ADMIN_EDIT
- ROLE_SONATA_USER_ADMIN_LIST
- ROLE_SONATA_USER_ADMIN_CREATE
# using the staff role to create new roles
ROLE_MANAGE_USERS: [ROLE_SONATA_USER_STAFF]

WSS 3.0 Site Provisioning

Is there any way to do WSS 3.0 site provisioning? My client's requirement is attributes as variables that will be defined in XML format: Organization Name, Logo, Address, User and Role information. The client should be able to install this web application to any WSS production server by just defining the attributes in the XML file.
Is it possible to to write a utility to parse that well defined XML and provision the site accordingly?
It's possible to provision sites from the object model, but creating entirely customized sites is beyond the scope of a single question. To get you started, you should take a look at the SPWebCollection.Add as well as the SPSiteCollection.Add.
To create a site collection and some subsites into one of your web applications, you could use something like this:
var farm = SPFarm.Local;
var solution = farm.Solutions.GetValue<SPSolution>("YourSolution.wsp");
var application = solution.DeployedWebApplications.First();
var sites = application.Sites;
using(var site = sites.Add("/", "Root Site", "Description", 1033, "YOURTEMPLATE#1", "YOURDOMAIN\SiteCollectionAdmin", "Site Collection Admin", "admin#yourcompany.example")) {
using(var rootWeb = site.RootWeb) {
// Code customizing root site goes here
using (var subSite = rootWeb.Webs.Add("SubSite", "Sub Site", "Description", 1033, "YOURTEMPLATE#2", false, false)) {
// Code customizing sub site goes here
}
}
}
Yes, there are more than one.
Take a look at SharePoint Solution Generator which is in Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions.
You may create a site with all requirements of yours (pages, lists, document libraries...) and then generate a VS project that will create a SharePoint feature with all of your site. Then you may deploy that feature to any WSS production server.
You may alter the VS project to implement the logic to read your attributes from an additional xml file.
If the structure of your site is plain or you can save it as a template you may also write a small console application that reads the attribute xml file and create the site.
Create a regular solution, or use the aforementioned solution generator to generate the .wsp file. Then create a small console application, that expects the variables you mentioned as parameters.
With the code listed above, provision the new sitecollection from that solution, and store the entered parameters (Company name etc.) in the site in a list, or in the SPSite.Properties propertybag, from which you can then read them in custom webparts etc..
The SharePoint Data Population Tool available on CodePlex allows you to define sites with XML.

SharePoint Development Permissions

Hi I am using the SharePoint namespace to pull items from various lists throughout the site. My web part works, but only on my account. When I try it on another account it gives me "Error: Access Denied" for the page. I have taken all web parts out and have only this web part on the page. When I remove the following lines the page loads for everyone, when I add it back in however it does not work. I am guessing this is some permission problem. I was wondering is there away to programatically query different lists on SharePoint by assigning a user id to use? Thank you for any help
...
SPSite site = new SPSite(_SPSite);
SPWeb eachWeb = site.AllWebs[0];
SPListItemCollection myItemCollection = eachWeb.Lists["Listings"].Items;
...
You're correct, the access denied error is occurring when you're using an account which does not have access to the "Listings" list in the current website.
The easiest way around the issue is to use a SPSecurity.RunWithElevatedPrivleges call:
SPSecurity.RunWithElevatedPrivleges(delegate()
{
//Your code here
});
which will run whatever code is contained in the anonymous method using the SharePoint/System account, granting complete control. Be careful when using this technique though, as it equivalent to running code at full trust with a super user account. There are other caveats to be aware of as well.
Try:
SPWeb eachWeb = SPContext.Current.Site.RootWeb.Webs[0];
SPListItemCollection myItemCollection = eachWeb.Lists["Listings"].Items;
Remember that SPWeb should be used in a using block, or disposed of explicitly after use.
As regards the first caveat from EvilGoatBob, I quote:
"If you're manipulating any Object Model elements within your elevated method, you need to get a fresh SPSite reference inside this call. For example
SPSecurity.RunWithElevatedPrivileges(delegate(){
SPSite mySite = new SPSite(http://sharepoint/);
SPWeb myWeb = SPSite.OpenWeb();
// further implementation omitted
});"
Notice that the site parameter is hard-coded - this is because of a bug. If you instead had tried:
using (SPSite site = new SPSite("http://" + System.Environment.MachineName)) {}
You would get the rather generic "No SharePoint Site exists at the specified URL..." error. This caused me no end of grief. Bottom line is that you have to hard-code the server name (unless anyone has an alternative). You can also get a similar error message when debugging Web Parts for the first time with VSeWSS 1.3.
You do not need to hardcode the server name in this case because your requirement is to retrieve items from list inside the same site as your webpart. You are correct, if you do not have enough privileges with your account, then you get the Access Denied. The solution is to create a new SPSite object within a different security context, and do your work:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb web = site.OpenWeb())
{
//the web object was retrieved with elevated privileges under the system account.
//do your work here:
SPListItemCollection myItemCollection = web.Lists["Listings"].Items;
//...
}
}
}
);
With the code above, your webpart is portable because there's no hardcoding, and runs in the correct security context while disposing of all unmanaged SPRequest objects created by the SPSite and SPWeb constructors.

Resources