Does anyone know of some good resources related to setting up heirarchical user account systems? I'm currently setting one up and am struggling with some of the more complex logic (especially with determining permissions). I was hoping I might be able to find some resources to help me along.
Some Background:
I'm building a user account system for a web CMS that allows for a nested group hierarchy. Each group can be allowed/denied access to read, write, add, and delete (either explicitly for that group, or implicitly by one of its parents). As if that weren't complicated enough, the system also allows for users to be members of multiple groups. -- This is where I'm stuck. I've got everything set up, but I'm struggling with the actual logic for determining pemissions for a given user.
The manual for CakePHP has an excellent description of how Access Control Lists work.
http://book.cakephp.org/2.0/en/core-libraries/components/access-control-lists.html
Represent the permissions set for a given group as a bit mask. OR-ing the bit masks together will give you the resultant permission set.
Update for #Alex:
I wrote this answer 3 years ago, but I believe I was alluding to the following...
From the question
a nested group hierarchy. Each group can be allowed/denied access to
read, write, add, and delete (either explicitly for that group, or
implicitly by one of its parents). As if that weren't complicated
enough, the system also allows for users to be members of multiple
groups. -- This is where I'm stuck. I've got everything set up, but
I'm struggling with the actual logic for determining pemissions for a
given user.
Assign a bitmask matching the total permission set of a group (or role) in the system:
e.g. 00 (using two bits keeps it simple here!)
The first bit confers Permission A and the second Permission B.
Now say Group A confers the following permission set: 01.
... and say Group B confers the following permission set: 10.
To get the resultant permission set for a user in an arbitrary set of groups you could perform a logical OR on the permission set bit masks:
Permission set for Group A 01
Permission set for Group B 10 OR
----
Resultant permission set 11 (i.e. both permission A and B are conferred)
I do not know the details of the questioner's system, but the system outlined here could be augmented to achieve different group-composition behaviors using different logical operators.
Look at the permissions in the Andrew File System. It allows users to create and administer groups of their own, while selectively assigning admin rights and ACLs. You might find that many of the pesky details are already worked out for you in their model.
Edit: here's a better link to AFS documentation:
http://www.cs.cmu.edu/~help/afs/index.html
Here's the section on groups:
http://www.cs.cmu.edu/~help/afs/afs_groups.html
I've done exactly this before and its no trivial implementation. You're going to want to look at the SecurityPermission class.
[http://msdn.microsoft.com/en-us/library/system.security.permissions.securitypermission.aspx][1]
I have done this before by utilizing XML (which I'm not sure I'd do again) and storing that XML as permission list inside of SQL server in an XML column through a CLR stored proc. The XML would have an element called a "permission" and then the permission would actually be a ENUM inside of the code. Each permission was a new implementation of the SecurityPermission class (linked above) Users were tied to groups which were defined in SQL server and then as the user was added/removed to groups, the XML doc would get updated to reflect which groups they were apart of.
As soon as the user logged in, the users credentials would be loaded into the application store (session) and then would be accessed accordingly. When authorization needed to take place the XMl in the application store would be pulled down loaded into the SecurityPermission via the "FromXML" method. At that point I would use the following methods to determine if the user had permission:
Demand
Intersect
Union
IsUnrestricted
IsSubSetOf
etc., etc, etc.
At that point after performing the Demand I was able to determine if the caller had access according to how I implemented my security routines in the SecurityPermissions.
Again, this is leaving out a TON of detail, but this should get you going down the right path.
Take a look at this name space as well: [2]: http://msdn.microsoft.com/en-us/library/system.security.permissions.aspx "System.Security.Permissions"
Related
I'm sure this has been answered before, but I can't quite figure out how to phrase exactly what I'm looking for.
I have an app where Users will have Permissions for Students and Cases. Some users will have Read access only, some Read.Write, some Write only, etc. This will apply to both Students and Cases. So Case.Read.Write wouldn't grant Student.Read.Write for example.
Then there is scope. Some users will have permissions for a single school. Some will have permissions for an entire district, some multiple schools, etc.
I'm trying to get the logic right at the level of defining the roles in the app. I'd like to be able to separate permission assignment from scope assignment, and I'd also like to be able to group different users together with combined permissions, for example: District Managers would cover Read, Write, Create, and Delete for all Students and all Cases in an entire District.
So far I have divided the permissions into Student and Case, and then allow for Read,Write,Create,Delete for each.
So my questions are:
Am I going about this the right way?
Can I group these within scope in Azure without including every single scenario? e.g. School.Student.Read.Write,District.Case.Delete, etc.?
Would I be better off handling scope at the external code level and only worrying about task permissions in AD?
Any feedback would be helpful.
How can I change the permissions in CKAN, so every editor/admin of an organization can add a group to a dataset (right now, the editor or admin has to be a member of the group to be able to add a certain group to a dataset)?
The dataportal I am developing only has 8 groups and every admin/editor should be able to add these groups to a dataset.
It seems to me that Group permissions are a bit of a hangover from the past (there was a time in CKAN without Organizations and only groups, and groups are based heavily on Organizations internally) and I wanted to make a proposal to the CKAN developers for providing an option to remove them (i.e. every Org editor or Admin can add anything to any group). Apart from that possibility there are a couple of workarounds:
Make everyone of these users a superuser (probably bad)
Make a "master" group which contains all existing groups (this is only
possible via the API) and then use the cascading authorization
configuration:
http://docs.ckan.org/en/latest/maintaining/configuration.html#ckan-auth-roles-that-cascade-to-sub-groups
Make an extension that hooks into the user creation process and
automatically adds all Org editors and Admins to all groups
Make an
extension that doesn't check or relaxes auth when trying to add
datasets to groups (this seems like overkill compared to the general
change I mentioned at the beginning: both would need to be coded and
I am more interested in doing the first one!)
This is going to be vague, hopefully not annoyingly so. I know very little about SharePoint, but I'm asking for someone who's more knowledgable but is under lots of crippling pressure. Unfortunately I'm going to be held responsible for the project (it's due before Christmas!!), so I need to see what I can figure out on my own to help out. Please allow my desperation and helplessness to excuse any problems with this question.
We've created an InfoPath form that generates xml files that will be uploaded to SharePoint. The data from these files will be aggregated and used to generate reports. The biggest issue is that the users will be spread out over three locations, and the info generated from each location needs to be firewalled from the others. But we need the xml files from all three locations to go to the same place in order to make the aggregation feasible with minimal manual work.
I've read something about SharePoint groups (http://technet.microsoft.com/en-us/library/cc262778%28v=office.14%29.aspx) and figured that might be the way of doing it, so long as 1) the xml documents could all go to the same library/repository and 2) that shared repository would only show each group their own documents. For at least two users we also need a master view that shows all of the documents regardless of the group that created them.
That's the main question. Ultimately we'll also need a similar way of storing the generated reports (tables and charts) to the creators of the xml files AND a set of users at each location who won't be able to view or create those xml files. But first things first, I guess.
Is this possible and feasible? Any hints/links that could get us started down this path?
I think in your case the best option is to create a folder for each group, and set permissions on them to allow just the specific group of users to access that folder. The same with a separate library for reports. Then, you'd just setup a list view that flattens the folder hierarchy to view all items at once.
You could also set per-document permission programmatically in an event receiver, however, there's a pretty low limit (search for ACL) on the number of unique access control lists per library (it's 50.000 actually). So depending on the number of XMLs you are going to manage you may reach this limit.
I am trying to design an efficient database schema for user settings in SQL Server 2008 R2. The wrinkle here is that we need multiple levels of granularity, and I'm not sure how to efficiently represent that.
We have a handful of settings that can be applied to a full Account, a single Module, or a specific Feature. Currently the way the table has been set up is something to the effect of:
AccountId int
ModuleId int
FeatureId int
SettingData string
(please don't get hung up on what SettingData is or isn't, I just made it a string here in the example to distinguish it from the other Ids).
Problem: Many customers have access to many modules, and these modules have access to many features. A single Account making a change to SettingData can modify 4000 records. This is absolutely not tenable for obvious reasons, and I'm determined to fix it.
The solution is obviously to have a few different tables that, by their usage, override eachother and allow some account wide settings and granular preferences. However, I've never done this before and my attempts at designing it end up looking disturbingly similar to the inefficient table structure we currently have.
Thanks in advance, any help is appreciated.
It sounds as though settings can currently be specified at the following levels:
Account
Module
Feature
Given that there are probably already tables set up for each of Account, Module and Feature, it would appear to make sense to:
Remove the existing table.
Set up a new field for setting data on each of the existing Account, Module and Feature tables.
Since the general principle is that the specific should override the general, a Module-level setting should override an Account-level setting, and a Feature-level setting should override a Module-level setting.
The advantage of this approach is that any time a specific setting was updated, only a single record would need to be updated.
The disadvantage is that to determine which setting should apply to a specific feature (for a specific account) in a specific module, 3 tables would have to be queried instead of one.
user.fld_usr_name is a string with the value random name
user is an object that is given as a parameter
ByVal user As GUser
this is the linq query that doesn't work
Dim result = (From usr In users Where usr.Name.Contains(user.fld_usr_name) Select usr).ToList()
this is the one that works
Dim result = (From usr In users Where usr.Name.Contains("random name") Select usr).ToList()
this is the error
Object reference not set to an instance of an object.
I am using this in Linq to Active Directory library
which probably means it's linq to entities
I've tried everything
I went up into the source code of that plugin.
LINQ just didn't work like it should with vb.net as with c#.
The plugin was C# code, but that shouldn't matter. Very strange.
I forgot the specifics since it has been a while, but it had to do something with the fact that it passes the property as a reference and not the value. Or the fact that it has to be a static... If I knew I'd fix it
I used a shared property to load all my users and worked with that.
If someone knows how to fix this bug, please let me know
another thought on this is that active directory has a really loose definition of what a "user" or "group" is. For instance, with groups; you have security groups and distribution groups. But AD maybe implemented as having something like security groups, authorization groups, distribution groups, location groups, etc. Then on top of that, your IT dept might have it set up so that OUs represent matrix groups and so on. But when you tell AD to bring you back a list of security groups, it'll bring you back EVERYTHING that used a security group type to create it.
Now, if you back up and look at it from the other direction, you'll find that not all "User" are actually users. Some are used differently and thus did not use "Name" property. I've run across this a few times where i had the connected drilled down into an OU that I thought was appropriate and then tried to bring back all the names in that OU. If the field isn't actually used, it'll come back as null and blow your application up. Is it poor AD design? Usually. A lot of organizations get into a habit of creating users or groups to accomplish tasks rather than doing it in a way that physically represents the organization. For instance, creating a user account that is used by a web application only, or creating new groups just to encompass a few permissions for a few special people like I described earlier. And the problem with this of course, is that you try to look at it from a database perspective when coding your application. But it's not a database; it's simply a collection of collections. An unstandardized, dynamic, flat file. :(
So as it possibly applies to you, your linq query maybe returning zilch because the Name field is in fact null for that collection. It is for this reason, that I now only use GUIDs or Native GUIDs. In cases where you only have a name, then use the searcher and grab guids, then use those guids to create a directory entry that WILL have the info you're looking for.