On 04/04/2012 04:01 PM, Scott Seago wrote:
On 04/04/2012 03:18 PM, Matt Wagner wrote:
So we're not talking about authentication data here -- that's all in
the session still. But for group membership, with a short enough
timeout/refresh interval we're _probably_ safe -- we're talking about
"propagation time" rather than erroneous permission results, really.
That said, we could do it in another way that avoid caching group
membership entirely (but it does complicate the permission checks,
preventing us from gaining the full benefit of the denormalization).
Essentially we could do the following:
1) denormalize _inherited_ permission relations as planned (i.e.
explicit records on the instance for users and groups with access from
whatever level in the hierarchy
2) do _not_ denormalize group members in the above -- i.e. if "Joe" is
in the "Engineering Management" group, and "Engineering Management"
has the "Pool Administrator" role in the Engineering pool, and we have
a "Redmine" deployment in that pool then we would not have a
denormalized permission record for "(Joe, Pool Administrator,
Redmine)" -- we would only have one for "(Engineering Management
Group, Pool Administrator, Redmine)"
3) for permissions checks, instead of simply doing a lookup on the
denormalized table for Joe, we'd have to look for both Group and
invididual grants, after pulling the current group assignments for the
current user
i.e. my proposal would leave just this for base permission checks:
return true obj.derived_permissions.find(:first, :include => [:role
=> :privileges],
:conditions => ["derived_permissions.user_id=:user and
privileges.target_type=:target_type and
privileges.action=:action",
{ :user => user.id,
:target_type => target_type.name,
:action => action}])
Instead we'd first need to pull the user's LDAP group list, and then
join _twice_ with permissions, once verifying user => user.id, and
again verifying group in user.groups
Scott
Oh wait, scratch that. I just remembered why I'd rejected this approach
early on. We've got to handle groups whether or not LDAP is enabled, so
we already have a need to manage local groups -- so the syncing with
LDAP (for group membership data, _not_ identity) was so that both
scenarios can use the same model. If we decide not to cache membership
in LDAP groups, we either need to merge the results of "what LDAP groups
does $user belong to" with "what local groups does $user belong to" or
denormalize local groups in the derived permissions model but still pull
remote groups realtime (for every permissions check)
Now I'm back to wondering what the big deal with syncing is as long as
the interval is fairly short. It's essentially equivalent to the LDAP
admin having made the user membership change $interval later -- so if
the interval is fairly short, there's little difference in overall effect.
Scott