You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@roller.apache.org by Dave <sn...@gmail.com> on 2007/07/12 22:50:17 UTC

New proposals for externalizing Roller user/permissions management

I'm working on two new proposals (see below) for externalizing user
and permissions management, which is something that I need and others
have requested, for example Elliot of Lulu.com and James Snell of IBM.
These proposals are not complete, but I'd like to get some feedback
now before I go too far into design.

So, interested parties, please take a look and provide feedback. Does
this meet our common requirements for externalized user profiles and
permissions? What about the implementation? See any red flags for
performance or scalability?

- Dave


Externalize User Management

For ease of installation and management, Roller is able to manage it's
own users without relying on any external system other than its RDBMS.
We definitely don't want to lose that that easiness, but as Roller
moves into enterprise scenarios where Directory Servers rule and
social networking scenarios where user profile information is key, we
need to make some changes. For Roller to be successful in large
organizations and social networks, we need to make it easy to
integrate Roller with existing user management systems. The way to do
that is to externalize user management, or rather to make it
externalizable.

This proposal outlines a plan to make it easy to hook Roller up to an
external user management system for user information, user profiles
and user roles. The general approach is to define a UserRepostory API,
provide a default implementation for Roller, and change UserManager to
use that API. Developer could then provide alternative implementations
of that API to plug in their own user management systems. Also, to
allow more authentication options make it possible to configure Roller
to use CMA instead of Acegi.

Read the rest here:
http://cwiki.apache.org/confluence/display/ROLLER/Proposal+Externalize+User+Management
AKA http://tinyurl.com/352ttm


Externalize User Permissions

For ease of installation and management, Roller is able to manage it's
own users permissions relying on any external system other than its
RDBMS. We don't want to lose that ability, but we do want to make it
possible to plug Roller into existing sites and applications that have
their own permissions management systems.

This proposal outlines a plan to make it easy to hook Roller up to an
external user permissions system. The general approach is to define a
User Permissions API, provide a default implementation for Roller, and
change UserManager to use that API. Developer could then provide
alternative implementations of that API to plug in their own user
permissions systems.

Read the rest here:
http://cwiki.apache.org/confluence/display/ROLLER/Proposal+Externalize+User+Permissions
AKA http://tinyurl.com/2rfpba

Re: New proposals for externalizing Roller user/permissions management

Posted by Dave <sn...@gmail.com>.
On 8/1/07, Allen Gilliland <al...@sun.com> wrote:
> I took a quick look through this and I think it's looking pretty good.
> I like the idea of using the java security stuff as the base for the
> permissions, that sounds very clean and extensible.

Thanks for the careful review. I need all the help I can get on this one.


> I like how the checkPermission(perm, user) method is very generic and
> simple, that seems like a very nice design.  So to take that design one
> step further, is there any reason why we really need to separate out the
> concept of roles vs. permissions any more?  Is there any reason to keep
> those separate in the data model any more?  i.e. what if we just had ...
>
> public void grantPermission(RollerPermission perm, User user);
>
> which would be a logic counterpart to the checkPermission(perm, user)
> method and would probably work similar to ...
>
>    if(perm instanceof GlobalPermission) {
>      // apply the user role
>    } else if(perm instanceof WeblogPermission) {
>      // grant weblog permission
>    } else {
>      // probably bad input
>    }
>
> this would further simplify the methods you mention because we would no
> longer need any of the grant/revoke methods, and instead of having get
> methods for roles vs. permissions we would just have getPermissions()
> methods.  would that work?
>
> i also like that you've redone the permission table, which seems to
> simplify things as well, but can we carry that on from my suggestion
> above and just store all permission data in that table, including roles
> and weblog permissions?  would that work?
>
> this way if you add all of that up we are greatly reducing the security
> framework into these methods ...
>
> public boolean checkPermission(RollerPermission perm, User user);
> public void grantPermission(RollerPermission perm, User user);
> public void revokePermission(RollerPermission perm, User user);
> public List<RollerPermission> getPermissions(User user);
>
> is that feasible?

Possibly. I am somewhat reluctant to remove the notion of Roles
because I believe they give us a way to hook into and take advantage
of standard Java EE security. Here are some reasons to keep the notion
of Roles:

* Java EE supports roles and provides an API for creating them (JACC).
It is not very well supported yet, but it's coming soon to a container
near you. Standard permissions support may be a long time coming.

* App servers can/do provide infrastructure for:
     - mapping external groups (e.g. LDAP groups) to roles
     - automatically placing users into roles based on realms

* Roles are a way to imply specific permissions

Another reason I'm reluctant is that I need to externalize user
management so Roller can be easily integrated with other systems. Some
of those systems don't support permissions yet, but they do support
Roles. My user manager may have to take the common denominator
approach of dealing only with Roles and I'll need the flexibility to
use Roles to imply Permissions.

- Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by Elliot Lee <el...@lulu.com>.
Allen Gilliland wrote:
> i also like that you've redone the permission table, which seems to 
> simplify things as well, but can we carry that on from my suggestion 
> above and just store all permission data in that table, including 
> roles and weblog permissions?  would that work?
>
> this way if you add all of that up we are greatly reducing the 
> security framework into these methods ...
>
> public boolean checkPermission(RollerPermission perm, User user);
> public void grantPermission(RollerPermission perm, User user);
> public void revokePermission(RollerPermission perm, User user);
> public List<RollerPermission> getPermissions(User user);
>
> is that feasible?

Hi,

Just a couple of notes:
    . I've discovered that the Lulu equivalent of checkPermission() has 
a big weakness: when permission is denied, there's no way to indicate to 
the user why. It'd be nice to think how the authz framework could 
indicate "server is down" versus "the administrator thinks you are a 
schmo", so that the user has more information beyond being told "You are 
not allowed to do that."
    . Also note that the possible outcome of permission checking could 
concievably go beyond "allowed" or denied". For example, if a user is 
trying to post a comment to a blog post, "requires_moderator_approval" 
is a valid checkPermission() result in addition to "allowed" and 
"denied". So it might make sense to return a PermissionResultCode 
instead of just a bool. I can't think of any other permissions checking 
result codes that might be needed beyond these three, but it's worth 
allowing for.
    . grantPermission & revokePermission may be combined into one 
routine: setPermission(RollerPermission perm, User user, 
PermissionResultCode result_code). If the authz framework needs to 
execute actions when a permissions is changed, it can do that work itself.
    . getPermissions() (and to some extent grantPermission & 
revokePermission) may not work in situations where the result of 
checkPermission() is a calculated result rather than a stored value. 
Just want to clarify whether grant/revoke/getPermissions will be called 
except in the Roller UI for editing permissions...

Best,
-- Elliot

Re: New proposals for externalizing Roller user/permissions management

Posted by Allen Gilliland <al...@sun.com>.
Dave,

I took a quick look through this and I think it's looking pretty good. 
I like the idea of using the java security stuff as the base for the 
permissions, that sounds very clean and extensible.

I like how the checkPermission(perm, user) method is very generic and 
simple, that seems like a very nice design.  So to take that design one 
step further, is there any reason why we really need to separate out the 
concept of roles vs. permissions any more?  Is there any reason to keep 
those separate in the data model any more?  i.e. what if we just had ...

public void grantPermission(RollerPermission perm, User user);

which would be a logic counterpart to the checkPermission(perm, user) 
method and would probably work similar to ...

   if(perm instanceof GlobalPermission) {
     // apply the user role
   } else if(perm instanceof WeblogPermission) {
     // grant weblog permission
   } else {
     // probably bad input
   }

this would further simplify the methods you mention because we would no 
longer need any of the grant/revoke methods, and instead of having get 
methods for roles vs. permissions we would just have getPermissions() 
methods.  would that work?

i also like that you've redone the permission table, which seems to 
simplify things as well, but can we carry that on from my suggestion 
above and just store all permission data in that table, including roles 
and weblog permissions?  would that work?

this way if you add all of that up we are greatly reducing the security 
framework into these methods ...

public boolean checkPermission(RollerPermission perm, User user);
public void grantPermission(RollerPermission perm, User user);
public void revokePermission(RollerPermission perm, User user);
public List<RollerPermission> getPermissions(User user);

is that feasible?

-- Allen


Dave wrote:
> I have withdrawn my two Roller 4.1 user/perms management proposals and
> replaced them with one proposal that incorporates feedback from Elliot
> and Allen:
> 
> " Proposal Externalize User And Permissions Management"
> http://tinyurl.com/28br55
> 
> Major changes
> - Removed User Repository API
> - Removed User Permssions API
> - Defined single consistent permssions system exposed via UserManager
> - Added details on specific changes to be made to implement the system
> 
> Comments and suggestions for improvement are more than welcome.
> 
> Thanks,
> - Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by Dave <sn...@gmail.com>.
Thanks for the feedback.


On 7/24/07, David Jencks <da...@yahoo.com> wrote:
> I've just glanced at this and may have further comments later.
>
> 1. I think that using Permissions is definitely the way to go.

Good. Glad you agree.


> 2. I think the proposal is still mixing permission evaluation with
> permission and user administration too much.  If a 3rd party system
> is managing users and permissions, it may well be completely
> impossible to administrate from roller at all: you may have to use
> the 3rd party tools.  So, I would like to see the administration
> aspects separated completely from authorization decisions.
>
> 3. In line with (2), in section 5.3 I think you need 2 interfaces:
> SecurityService
> boolean checkPermission(RollerPermission perm, User user);
>
> SecurityManager
> // A way for the Roller front-end to grant and revoke roles because
> roles imply global permissions
> void grantRole(String roleName, User user);
> void revokeRole(String roleName, User user);
>
> // The Roller front-end also needs to be able to grant and revoke
> weblog permissions
> void grantWeblogPermission(WeblogPermission perm, User user);
> void revokeWeblogPermission(WeblogPermssion perm, User user);
>
> // and to display the roles and permissions associated with each user:
> List<String> getRoles(User user);
> List<WeblogPermission> getWeblogPermssions(User user);
> List<WeblogPermission> getWeblogPermssions(Weblog weblog);

Regarding SecurityService and SecurityManager, I'd rather not
complicate things by adding additional interfaces beyond UserManager.

My current thinking is that If you hook Roller up to an external
user/perm management system and that system does not support writes of
user/perm information, then you should:

1) disable/hide the parts of the Roller UI that support user/perm/role editing

2) impl. the write methods in UserManager to throw
UnsupportedOperation exceptions


> 4.  I am a bit of a JACC fanatic, but I think the
> SecurityService.checkPermission method should only have the user as a
> parameter.  The container roller is running in should be tracking the
> user, not roller itself.  This is how javaee and jacc work, I don't
> know how compatible it is with acegi.

You meant to say "only have the permission as the parameter", no?

The Roller backend must be able to run outside of a container, so I'm
against that change.

And BTW, I'm definitely not a JACC fanatic, it it frighteningly
complex and it is not supported on most containers. And it can't
really handle dynamic permissions. I hope something better will come
along.


> So, I see this as being more or less two applications that may not be
> running on the same server:
>
> web log editing, creation, viewing, etc etc.  This could be a more or
> less standard web app that doesn't need to know anything about the
> user  except their "preferences", but nothing security related: all
> security info is hidden behind the checkPermission method.
>
> user management where you can, well, manage users and their permissions.
>
> --------------------------
> relationship to javaee and jacc security
>
> The blog specific roller permissions may not fit incredibly well into
> a plain vanilla javaee security framework.  javaee security is based
> on the idea that an app has a fixed, known set of roles, and that
> permissions are assigned to roles.  Then some external magic maps
> users to permissions.

Right. I don't think Java EE or even JACC can help much here.


> So,
> create blog b1
> add user A.
> How do you allow A access to b1, but prevent user B from accessing b1?
>
> in the javaee model, there would have to be a role mapped to the b1
> permissions, that we could assign to A but not B.
>
> AFAICT you really need a more dynamic or direct user <> permission
> mapping than is provided by plain javaee security.  I don't know what
> other systems offer but I'm working intermittently on one system that
> does offer stuff like this, apache directory's triplesec project.

Yes. I am convinced that we cannot use plain Java EE security to
manage user-weblog permissions and I've had lengthly conversations
with Sun's Java EE security architect to back that up.

- Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by David Jencks <da...@yahoo.com>.
I've just glanced at this and may have further comments later.

1. I think that using Permissions is definitely the way to go.

2. I think the proposal is still mixing permission evaluation with  
permission and user administration too much.  If a 3rd party system  
is managing users and permissions, it may well be completely  
impossible to administrate from roller at all: you may have to use  
the 3rd party tools.  So, I would like to see the administration  
aspects separated completely from authorization decisions.

3. In line with (2), in section 5.3 I think you need 2 interfaces:
SecurityService
boolean checkPermission(RollerPermission perm, User user);

SecurityManager
// A way for the Roller front-end to grant and revoke roles because  
roles imply global permissions
void grantRole(String roleName, User user);
void revokeRole(String roleName, User user);

// The Roller front-end also needs to be able to grant and revoke  
weblog permissions
void grantWeblogPermission(WeblogPermission perm, User user);
void revokeWeblogPermission(WeblogPermssion perm, User user);

// and to display the roles and permissions associated with each user:
List<String> getRoles(User user);
List<WeblogPermission> getWeblogPermssions(User user);
List<WeblogPermission> getWeblogPermssions(Weblog weblog);

4.  I am a bit of a JACC fanatic, but I think the  
SecurityService.checkPermission method should only have the user as a  
parameter.  The container roller is running in should be tracking the  
user, not roller itself.  This is how javaee and jacc work, I don't  
know how compatible it is with acegi.

So, I see this as being more or less two applications that may not be  
running on the same server:

web log editing, creation, viewing, etc etc.  This could be a more or  
less standard web app that doesn't need to know anything about the  
user  except their "preferences", but nothing security related: all  
security info is hidden behind the checkPermission method.

user management where you can, well, manage users and their permissions.

--------------------------
relationship to javaee and jacc security

The blog specific roller permissions may not fit incredibly well into  
a plain vanilla javaee security framework.  javaee security is based  
on the idea that an app has a fixed, known set of roles, and that  
permissions are assigned to roles.  Then some external magic maps  
users to permissions.

So,
create blog b1
add user A.
How do you allow A access to b1, but prevent user B from accessing b1?

in the javaee model, there would have to be a role mapped to the b1  
permissions, that we could assign to A but not B.

AFAICT you really need a more dynamic or direct user <> permission  
mapping than is provided by plain javaee security.  I don't know what  
other systems offer but I'm working intermittently on one system that  
does offer stuff like this, apache directory's triplesec project.

thanks
david jencks


On Jul 24, 2007, at 9:16 AM, Dave wrote:

> I have withdrawn my two Roller 4.1 user/perms management proposals and
> replaced them with one proposal that incorporates feedback from Elliot
> and Allen:
>
> " Proposal Externalize User And Permissions Management"
> http://tinyurl.com/28br55
>
> Major changes
> - Removed User Repository API
> - Removed User Permssions API
> - Defined single consistent permssions system exposed via UserManager
> - Added details on specific changes to be made to implement the system
>
> Comments and suggestions for improvement are more than welcome.
>
> Thanks,
> - Dave


Re: New proposals for externalizing Roller user/permissions management

Posted by Dave <sn...@gmail.com>.
I have withdrawn my two Roller 4.1 user/perms management proposals and
replaced them with one proposal that incorporates feedback from Elliot
and Allen:

" Proposal Externalize User And Permissions Management"
http://tinyurl.com/28br55

Major changes
- Removed User Repository API
- Removed User Permssions API
- Defined single consistent permssions system exposed via UserManager
- Added details on specific changes to be made to implement the system

Comments and suggestions for improvement are more than welcome.

Thanks,
- Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by Allen Gilliland <al...@sun.com>.

Dave wrote:
> Thanks for the feedback. Comments are inline below.
> 
> 
> On 7/19/07, Allen Gilliland <al...@sun.com> wrote:
>> My initial thoughts ...
>> In general I think it's a nice thing to make Roller more flexible in
>> terms of plugging into external systems, but I'm also a bit suspicious
>> that some of this work is going to complicate things for typical
>> scenario users in order to support a much smaller number of more
>> enterprise type users.  At the risk of sounding too cautious, my biggest
>> fear with this proposal is that we are going to over complicate things.
>>   We already have a system that works well and it's not *too* difficult
>> to plug it into larger systems, so the point is that we have to draw the
>> line somewhere in terms for what work we do to support more specialized
>> types of installations and some of the work in this proposal is near
>> that line in my eyes.
>>
>> General feelings aside though, some thoughts on the details ...
>>
>> Externalize User Management.
>>
>> I don't think we need a new "UserRepository API", that is the same thing
>> as the existing UserManager.  I think the approach for plugging in an
>> external user system is just to plug in an alternate implementation of
>> the UserManager interface which should have all the right methods
>> available for dealing with users.  As you outline in your proposal, we
>> would need to change a fair amount of code so that instead of relying on
>> pojo relationships to fetch users we would need to consult the
>> UserManager everywhere, which is a bit of a PITA.
> 
> On second thought I agree with you on this. We do not need a User
> Repository API or a User Permissions API. The UserManger is the API,
> it's the right level at which to plugin external systems.
> 
> With that in mind, it really does not make sense for the UserManager
> to incude all of those page and website methods. Those should be
> moved. I suggest this:
> 
>   UserManager - for user and role/permissions management
>   WeblogManager - for Weblog and Page management
>   WeblogEntryManager - for WeblogEntry and Comment management
> 
> How do folks feel about that refactoring?


+1, that sounds like a good way to break things up to me.

-- Allen


> 
> 
>> I would also fairly strongly side with option #3.  At the end of the day
>> I don't think we should be setting up funky ways of partitioning profile
>> data so that you have to get a User and then call User.getProfile() to
>> get the rest of the profile data.  The User object should be all that is
>> needed and it can come from whatever system is configured.  The goal is
>> transparency and #3 is the best option in that regard.
> 
> I think we'll need extensible user attributes at some point, but for
> now using the User object can meet all of my requirements. So #3 works
> for me.
> 
> 
>> Externalize User Permissions
>>
>> This is where things get yucky IMO and this is also where I start to
>> believe that we are likely to complicate a simple, and already working,
>> solution just for a very small number of people who would run Roller
>> this way.
> 
> I disagree with that sentiment. Roller's biggest advantages are it's
> abilities to handle large mutli-weblog sites and in such sites it is
> almost always a requirement to hook into to user management
> permissions systems.
> 
> 
>> But if we really need to do this then same as above, I don't
>> see why we need a new "User Permissions API", we have the UserManager
>> interface and that should be enough.  Adding in more interfaces and APIs
>> seems unnecessary to me.  If we need to rework the UserManager methods
>> which deal with permissions checking then that's fine, but I think those
>> methods should remain in the UserManager.
> 
> Agree. The UserManger is the API, it's the right level at which to
> plugin external systems.
> 
> 
>> Like the user object, the biggest issue with trying to externalize
>> permissions the way you are proposing is that you are asking us to break
>> our object association model used by our ORM solution.  This is the part
>> of your proposal that makes me the most nervous.
> 
> It is a big change, but I believe we need it.
> 
> 
>> Other considerations ...
>>
>> Your design seems very intent on trying to call out to 3rd party systems
>> directly rather than just allowing a 3rd party system to control Roller,
>> why is that?
>>
>> Much of what you are proposing here could be done in a
>> different way where instead of focusing on changing the apis so that
>> accessing the data makes calls to 3rd party systems, we could instead
>> focus on allowing 3rd party systems have easier ways of controlling
>> Roller.  so instead of calling out to a 3rd party system to check
>> permissions, that system would notify Roller that userX now has
>> permissionY on blogZ when a permission change happens.  A very modest
>> event management system (something Roller needs anyways) would be
>> perfect for this.  This way changes happening in external systems can be
>> easily reflected in Roller by firing off an event like ... user profile
>> update, or user permissions change, etc, etc.
> 
> I believe that ideally Roller should provide both a Provisioning API
> so an external system can control users/weblogs and also pluggable
> user/permissions management.
> 
> My team decided against using a Provisioning API because it is to
> problematic and has too many moving parts. The controlling system has
> to keep things in sync, disabling blogs and users when employees
> leave, etc.
> 
> 
>> Mucking around with the backend systems and data model of Roller seems
>> to me like a more intrusive and highly coupled solution than just trying
>> to allow an external system the ability to somewhat remotely manage some
>> pieces of Roller.
> 
> What I'm proposing is making Roller more pluggable with a minimum
> amount of changes to the data model. I want to make things pluggable
> and less highly coupled.
> 
> 
>> One of the other major problems I see with trying to talk directly to
>> 3rd party systems is performance.  Constantly making calls to these 3rd
>> party systems is going to make performance management a pain because
>> instead of just worrying about Roller and how it performs on its own you
>> now have to worry about a whole string of interdependencies and remote
>> system calls which can all become bottlenecks.  Remember that if looking
>> up a User object requires a call to a remote system then if I want to
>> display 30 entries and show the authors name then that equals 30 calls
>> to that system and I will have minimal ways to optimize those calls on
>> Roller's end of things.  So from a performance point of view I would be
>> more worried about trying to keep all of these 3rd party systems
>> separate and continuously make remote calls between them.
> 
> Yes, performance is definitely a concern but if we design this right
> it should only be a concern for those plugging in external user
> management.
> 
> I'm going to rewrite and combine the two proposals into one with this
> feedback in mind. I hope to be done by mid-week.
> 
> Thanks,
> - Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by Dave <sn...@gmail.com>.
Thanks for the feedback. Comments are inline below.


On 7/19/07, Allen Gilliland <al...@sun.com> wrote:
> My initial thoughts ...
> In general I think it's a nice thing to make Roller more flexible in
> terms of plugging into external systems, but I'm also a bit suspicious
> that some of this work is going to complicate things for typical
> scenario users in order to support a much smaller number of more
> enterprise type users.  At the risk of sounding too cautious, my biggest
> fear with this proposal is that we are going to over complicate things.
>   We already have a system that works well and it's not *too* difficult
> to plug it into larger systems, so the point is that we have to draw the
> line somewhere in terms for what work we do to support more specialized
> types of installations and some of the work in this proposal is near
> that line in my eyes.
>
> General feelings aside though, some thoughts on the details ...
>
> Externalize User Management.
>
> I don't think we need a new "UserRepository API", that is the same thing
> as the existing UserManager.  I think the approach for plugging in an
> external user system is just to plug in an alternate implementation of
> the UserManager interface which should have all the right methods
> available for dealing with users.  As you outline in your proposal, we
> would need to change a fair amount of code so that instead of relying on
> pojo relationships to fetch users we would need to consult the
> UserManager everywhere, which is a bit of a PITA.

On second thought I agree with you on this. We do not need a User
Repository API or a User Permissions API. The UserManger is the API,
it's the right level at which to plugin external systems.

With that in mind, it really does not make sense for the UserManager
to incude all of those page and website methods. Those should be
moved. I suggest this:

   UserManager - for user and role/permissions management
   WeblogManager - for Weblog and Page management
   WeblogEntryManager - for WeblogEntry and Comment management

How do folks feel about that refactoring?


> I would also fairly strongly side with option #3.  At the end of the day
> I don't think we should be setting up funky ways of partitioning profile
> data so that you have to get a User and then call User.getProfile() to
> get the rest of the profile data.  The User object should be all that is
> needed and it can come from whatever system is configured.  The goal is
> transparency and #3 is the best option in that regard.

I think we'll need extensible user attributes at some point, but for
now using the User object can meet all of my requirements. So #3 works
for me.


> Externalize User Permissions
>
> This is where things get yucky IMO and this is also where I start to
> believe that we are likely to complicate a simple, and already working,
> solution just for a very small number of people who would run Roller
> this way.

I disagree with that sentiment. Roller's biggest advantages are it's
abilities to handle large mutli-weblog sites and in such sites it is
almost always a requirement to hook into to user management
permissions systems.


>But if we really need to do this then same as above, I don't
> see why we need a new "User Permissions API", we have the UserManager
> interface and that should be enough.  Adding in more interfaces and APIs
> seems unnecessary to me.  If we need to rework the UserManager methods
> which deal with permissions checking then that's fine, but I think those
> methods should remain in the UserManager.

Agree. The UserManger is the API, it's the right level at which to
plugin external systems.


> Like the user object, the biggest issue with trying to externalize
> permissions the way you are proposing is that you are asking us to break
> our object association model used by our ORM solution.  This is the part
> of your proposal that makes me the most nervous.

It is a big change, but I believe we need it.


> Other considerations ...
>
> Your design seems very intent on trying to call out to 3rd party systems
> directly rather than just allowing a 3rd party system to control Roller,
> why is that?
>
> Much of what you are proposing here could be done in a
> different way where instead of focusing on changing the apis so that
> accessing the data makes calls to 3rd party systems, we could instead
> focus on allowing 3rd party systems have easier ways of controlling
> Roller.  so instead of calling out to a 3rd party system to check
> permissions, that system would notify Roller that userX now has
> permissionY on blogZ when a permission change happens.  A very modest
> event management system (something Roller needs anyways) would be
> perfect for this.  This way changes happening in external systems can be
> easily reflected in Roller by firing off an event like ... user profile
> update, or user permissions change, etc, etc.

I believe that ideally Roller should provide both a Provisioning API
so an external system can control users/weblogs and also pluggable
user/permissions management.

My team decided against using a Provisioning API because it is to
problematic and has too many moving parts. The controlling system has
to keep things in sync, disabling blogs and users when employees
leave, etc.


> Mucking around with the backend systems and data model of Roller seems
> to me like a more intrusive and highly coupled solution than just trying
> to allow an external system the ability to somewhat remotely manage some
> pieces of Roller.

What I'm proposing is making Roller more pluggable with a minimum
amount of changes to the data model. I want to make things pluggable
and less highly coupled.


> One of the other major problems I see with trying to talk directly to
> 3rd party systems is performance.  Constantly making calls to these 3rd
> party systems is going to make performance management a pain because
> instead of just worrying about Roller and how it performs on its own you
> now have to worry about a whole string of interdependencies and remote
> system calls which can all become bottlenecks.  Remember that if looking
> up a User object requires a call to a remote system then if I want to
> display 30 entries and show the authors name then that equals 30 calls
> to that system and I will have minimal ways to optimize those calls on
> Roller's end of things.  So from a performance point of view I would be
> more worried about trying to keep all of these 3rd party systems
> separate and continuously make remote calls between them.

Yes, performance is definitely a concern but if we design this right
it should only be a concern for those plugging in external user
management.

I'm going to rewrite and combine the two proposals into one with this
feedback in mind. I hope to be done by mid-week.

Thanks,
- Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by Allen Gilliland <al...@sun.com>.
My initial thoughts ...

In general I think it's a nice thing to make Roller more flexible in
terms of plugging into external systems, but I'm also a bit suspicious
that some of this work is going to complicate things for typical
scenario users in order to support a much smaller number of more
enterprise type users.  At the risk of sounding too cautious, my biggest
fear with this proposal is that we are going to over complicate things.
  We already have a system that works well and it's not *too* difficult
to plug it into larger systems, so the point is that we have to draw the
line somewhere in terms for what work we do to support more specialized
types of installations and some of the work in this proposal is near
that line in my eyes.

General feelings aside though, some thoughts on the details ...

Externalize User Management.

I don't think we need a new "UserRepository API", that is the same thing
as the existing UserManager.  I think the approach for plugging in an
external user system is just to plug in an alternate implementation of
the UserManager interface which should have all the right methods
available for dealing with users.  As you outline in your proposal, we 
would need to change a fair amount of code so that instead of relying on 
pojo relationships to fetch users we would need to consult the 
UserManager everywhere, which is a bit of a PITA.

I would also fairly strongly side with option #3.  At the end of the day
I don't think we should be setting up funky ways of partitioning profile
data so that you have to get a User and then call User.getProfile() to
get the rest of the profile data.  The User object should be all that is
needed and it can come from whatever system is configured.  The goal is 
transparency and #3 is the best option in that regard.


Externalize User Permissions

This is where things get yucky IMO and this is also where I start to
believe that we are likely to complicate a simple, and already working,
solution just for a very small number of people who would run Roller
this way.  But if we really need to do this then same as above, I don't 
see why we need a new "User Permissions API", we have the UserManager 
interface and that should be enough.  Adding in more interfaces and APIs 
seems unnecessary to me.  If we need to rework the UserManager methods 
which deal with permissions checking then that's fine, but I think those 
methods should remain in the UserManager.

Like the user object, the biggest issue with trying to externalize 
permissions the way you are proposing is that you are asking us to break 
our object association model used by our ORM solution.  This is the part 
of your proposal that makes me the most nervous.


Other considerations ...

Your design seems very intent on trying to call out to 3rd party systems
directly rather than just allowing a 3rd party system to control Roller, 
why is that?  Much of what you are proposing here could be done in a 
different way where instead of focusing on changing the apis so that 
accessing the data makes calls to 3rd party systems, we could instead 
focus on allowing 3rd party systems have easier ways of controlling 
Roller.  so instead of calling out to a 3rd party system to check 
permissions, that system would notify Roller that userX now has 
permissionY on blogZ when a permission change happens.  A very modest 
event management system (something Roller needs anyways) would be 
perfect for this.  This way changes happening in external systems can be 
easily reflected in Roller by firing off an event like ... user profile 
update, or user permissions change, etc, etc.

Mucking around with the backend systems and data model of Roller seems 
to me like a more intrusive and highly coupled solution than just trying 
to allow an external system the ability to somewhat remotely manage some 
pieces of Roller.

One of the other major problems I see with trying to talk directly to 
3rd party systems is performance.  Constantly making calls to these 3rd 
party systems is going to make performance management a pain because 
instead of just worrying about Roller and how it performs on its own you 
now have to worry about a whole string of interdependencies and remote 
system calls which can all become bottlenecks.  Remember that if looking 
up a User object requires a call to a remote system then if I want to 
display 30 entries and show the authors name then that equals 30 calls 
to that system and I will have minimal ways to optimize those calls on 
Roller's end of things.  So from a performance point of view I would be 
more worried about trying to keep all of these 3rd party systems 
separate and continuously make remote calls between them.

-- Allen


Dave wrote:
> I'm working on two new proposals (see below) for externalizing user
> and permissions management, which is something that I need and others
> have requested, for example Elliot of Lulu.com and James Snell of IBM.
> These proposals are not complete, but I'd like to get some feedback
> now before I go too far into design.
> 
> So, interested parties, please take a look and provide feedback. Does
> this meet our common requirements for externalized user profiles and
> permissions? What about the implementation? See any red flags for
> performance or scalability?
> 
> - Dave
> 
> 
> Externalize User Management
> 
> For ease of installation and management, Roller is able to manage it's
> own users without relying on any external system other than its RDBMS.
> We definitely don't want to lose that that easiness, but as Roller
> moves into enterprise scenarios where Directory Servers rule and
> social networking scenarios where user profile information is key, we
> need to make some changes. For Roller to be successful in large
> organizations and social networks, we need to make it easy to
> integrate Roller with existing user management systems. The way to do
> that is to externalize user management, or rather to make it
> externalizable.
> 
> This proposal outlines a plan to make it easy to hook Roller up to an
> external user management system for user information, user profiles
> and user roles. The general approach is to define a UserRepostory API,
> provide a default implementation for Roller, and change UserManager to
> use that API. Developer could then provide alternative implementations
> of that API to plug in their own user management systems. Also, to
> allow more authentication options make it possible to configure Roller
> to use CMA instead of Acegi.
> 
> Read the rest here:
> http://cwiki.apache.org/confluence/display/ROLLER/Proposal+Externalize+User+Management 
> 
> AKA http://tinyurl.com/352ttm
> 
> 
> Externalize User Permissions
> 
> For ease of installation and management, Roller is able to manage it's
> own users permissions relying on any external system other than its
> RDBMS. We don't want to lose that ability, but we do want to make it
> possible to plug Roller into existing sites and applications that have
> their own permissions management systems.
> 
> This proposal outlines a plan to make it easy to hook Roller up to an
> external user permissions system. The general approach is to define a
> User Permissions API, provide a default implementation for Roller, and
> change UserManager to use that API. Developer could then provide
> alternative implementations of that API to plug in their own user
> permissions systems.
> 
> Read the rest here:
> http://cwiki.apache.org/confluence/display/ROLLER/Proposal+Externalize+User+Permissions 
> 
> AKA http://tinyurl.com/2rfpba


Problem telling roller to use custom FileManager

Posted by "Matthew P. Schmidt" <ma...@dzone.com>.
Hi guys.  We're in the middle of trying to replace the stock 
FileManagerImpl with our own implementation and there are two issues.  
First, getRealPath is private, which if it wasn't, we could just 
subclass FileManagerImpl and change that code, since its private, it 
looks like we need to copy nearly all the code.  Second, it doesn't 
appear that the property in roller-custom.properties:

persistence.filemanager.classname=org.apache.roller.business.FileManagerImpl

is actually doing anything :)  Is this the right property to override?  
We're running 3.1 right now on Tomcat 6.

-Matt

Allen Gilliland wrote:
> Sure, you can populate the page with whatever you want.
>
> I would check out the PageModel and SiteModel classes and look at the 
> methods those provide.  Those both provide a handful of ways to get 
> collections of entries that you could use to display on your frontpage.
>
> Alternatively, the rendering process is very pluggable, so you can 
> create your own model classes if you want and those classes can 
> contain access to anything at all.  You could use them to pull data 
> from Roller that isn't usually exposed, you could pull data from 
> custom tables in your database if you need to, or you could pull data 
> from web services or anywhere else you want.
>
> -- Allen
>
>
> Matthew P. Schmidt wrote:
>> Hi guys.  At JRoller we had a custom frontpage data model that 
>> fetched only the entries in a certain set of categories.  This was a 
>> hack and required us to override too much code.  Is there a cleaner 
>> way for us to replace the entry list coming to the frontpage theme 
>> (we're building a new one anyway)?
>> Thanks,
>> Matt
>>

Re: Modified Frontpage data model

Posted by Allen Gilliland <al...@sun.com>.
Sure, you can populate the page with whatever you want.

I would check out the PageModel and SiteModel classes and look at the 
methods those provide.  Those both provide a handful of ways to get 
collections of entries that you could use to display on your frontpage.

Alternatively, the rendering process is very pluggable, so you can 
create your own model classes if you want and those classes can contain 
access to anything at all.  You could use them to pull data from Roller 
that isn't usually exposed, you could pull data from custom tables in 
your database if you need to, or you could pull data from web services 
or anywhere else you want.

-- Allen


Matthew P. Schmidt wrote:
> Hi guys.  At JRoller we had a custom frontpage data model that fetched 
> only the entries in a certain set of categories.  This was a hack and 
> required us to override too much code.  Is there a cleaner way for us to 
> replace the entry list coming to the frontpage theme (we're building a 
> new one anyway)?
> Thanks,
> Matt
> 

Modified Frontpage data model

Posted by "Matthew P. Schmidt" <ma...@dzone.com>.
Hi guys.  At JRoller we had a custom frontpage data model that fetched 
only the entries in a certain set of categories.  This was a hack and 
required us to override too much code.  Is there a cleaner way for us to 
replace the entry list coming to the frontpage theme (we're building a 
new one anyway)? 

Thanks,
Matt


Re: New proposals for externalizing Roller user/permissions management

Posted by Elliot Lee <el...@lulu.com>.
Dave wrote:
> Yes, when Roller is used with an externalized perms system the
> existing Roller permssions UI should be disabled, do we also need
> links to the external perms management UI?
Hi Dave,

It'd be nice to have the option, yes. I think the permissions UI stuff 
might be a little more complicated to externalize, mainly because there 
are UI aspects of authorization that go beyond management. The most 
prominent example I can think of is the ability for the authz system to 
send back a little explanation back to the UI side of things as to why 
the user is not allowed to perform an action. Right now on Lulu.com, 
there are some spots that just say "You are not allowed to do that" when 
someone tries to do something that's not allowed (because I didn't 
design LPermissionManager properly :-). Optimally, it'd be possible for 
the authz system to tell the Roller user a little more about why the 
access was denied, and what steps the user can take to correct things 
("To post to this blog, you must first join the FOO group. You can join 
FOO by clicking >here<")

Also, I just thought of another set of issues that might need a little 
thought - what happens when people try to mix external authn/authz 
systems with the Roller internal ones. For example, what if someone 
wants to use an external authn system with the Roller authz system, or 
(this is where it gets weird) the Roller authn system with an external 
authz system? The cases of external+external and Roller+Roller are 
likely to be the most common cases. I don't think it's necessarily 
important to support the other combinations so much as be clear about 
what is supported and what isn't...

Best,
-- Elliot

Re: New proposals for externalizing Roller user/permissions management

Posted by Dave <sn...@gmail.com>.
On 7/12/07, Elliot Lee <el...@lulu.com> wrote:
> Hi Dave and others,
> Looks like an interesting start. Here are some comments :)
> On externalizing user management...
>
> Abstracting the directory of user profiles: In 2.1.2 (Possible
> solutions), possible solution #1, you state that the user object is
> needed because it's used in joins and queries. There's no fundamental
> reason that I can see why it is needed in the big picture. The only
> thing you really need to know about the user is a unique identifier.
> Roller looks like it uses random hex strings, while Lulu's system
> happens to use consecutive integers. Unless hibernate requires The
> userID should be the only thing that needs to be stored within Roller -
> all the other details should be retrieved from the UserDirectory on
> demand. I don't know if hibernate needs a user table there just to
> satisfy foreign key constraints from other objects that are owned by a
> user, though.

Perhaps I'm being to conservative here, but I'd like to keep our
existing queries and foreign key relationships in-tact for users.


> User profile modification: It's definitely nice to abstract this at the
> API level, but I think it's also important to take it into account at
> the UI level. Some installations (e.g. Lulu) may want to require users
> to use their own UI's for editing settings such as password, locale,
> etc. It's worth considering a bit more about how this abstracting can
> happen at the UI layer as well.

> For example maybe it'd be good to allow
> the sysadmin to configure URLs for a login page, logout page,
> registration page, profile editing page, etc.)

Good feedback. I think that should be part of the proposal.


> I think it's also important at the API level, a UserDirectory implementation is not
> required to implement the profile saving methods. The profile saving
> methods are really important only to the pieces of roller that tie in
> with the roller UI's to do that...

Correct. And those methods are only important when Roller is running
standalone without an external user mgmt/perms system.


> Authentication: Acegi looked fairly powerful & flexible for Lulu's
> needs. It seemed reasonably easy to implement a
> LuluAuthenticationProvider. I think the main hangup was more on the
> roller side - the implicit passing of RollerUserDetails between Acegi
> and CustomUserRegistry seems like a hack. I guess this is really more a
> problem on the user directory side of things than in the actual
> authentication functionality, though. If Acegi is going to continue to
> be an option, it needs to be made clear how acegi authentication
> providers are going to provide directory info to Roller.

I definitely want Acegi to remain an option so you are correct, my
design needs to account for how externalized auth will work with
Acegi.


> On the authorization side of user management: this really seems to tie
> in with externalizing user permissions. I see global roles as no
> different from per-blog permissions or per-post permissions or
> per-comment permissions (etc. etc.) So...

My initial thinking was that global roles come from the Java EE
authorization system but weblog permissions are different because they
are Roller application specific.

After looking at how a couple other popular Java web applications
handle auth/auth and externalization, I'm starting to rethink that.


> On externalizing user permissions:
>
> I'm really not big on the approach suggested - it doesn't seem general
> enough to allow tying in a wide range of authorization systems. From my
> perspective, I'd like to see something like the following:
>     bool canExecuteOperation(Object subject, String operation, Object
> on_object, Object[] context);
>
>          'subject' would identify the user who wants to carry out this
> particular action (e.g. 'Joe')
>          'operation' would identify the action the user is trying to
> carry out (e.g. 'edit an existing comment')
>          'on_object' would identify the object (if any) that the user is
> trying to execute the operation on (for example 'comment #1234')
>          'context' could identify some objects that are relevant to the
> operation (for example 'blog #43' and 'blog post #432', because Joe is
> trying to edit his comment #1234 which was previously submitted to blog
> post #432 in blog #43)
>
> The approach above allows for authorization implementations that have no
> way to answer the question "what operations is this user allowed to
> do?". The Lulu permissions manager is an example - although some of the
> yes/no authorization decision is driven by settings stored in the
> database, it is mostly code-driven and has to take into account
> situations such as moderated submissions, and book listings exclusive to
> one group.
>
> At the same time, the approach above should still accommodates
> authorization implementations that offer an API similar to the one you
> proposed. This approach also allows the authorization system to define
> and manage roles internally, and decide how those roles map to specific
> operations.

Yes, I like that type of approach better too and I think it aligns
better with standard Java security (principals, policy, etc.).


> I'm not sure about including permissions updates/editing in the API.
> This mainly goes back to the UI issues mentioned in my comments on
> authentication. Yes, Roller has UI to manage permissions, but that's
> only because it also has code to manage permissions. The UI for this
> feature should be abstracted along with the code, so that the
> RollerPermissionsEditingAPI is implemented by the
> RollerDefaultPermissionsImplementation code and only used by the
> RollerDefaultPermissionsImplementation UI/controller. I think it's
> fairly likely that plugging in new authorization systems will require
> plugging in new UI as well.

Yes, when Roller is used with an externalized perms system the
existing Roller permssions UI should be disabled, do we also need
links to the external perms management UI?


> There are lots of pieces of Roller that I don't understand yet, which
> means a lot of this may be totally off. Please let me know what doesn't
> make sense :)

Thanks for the feedback. I'm working on another rev of the proposal now.

- Dave

Re: New proposals for externalizing Roller user/permissions management

Posted by Elliot Lee <el...@lulu.com>.
Hi Dave and others,

Looks like an interesting start. Here are some comments :)

On externalizing user management...

Abstracting the directory of user profiles: In 2.1.2 (Possible 
solutions), possible solution #1, you state that the user object is 
needed because it's used in joins and queries. There's no fundamental 
reason that I can see why it is needed in the big picture. The only 
thing you really need to know about the user is a unique identifier. 
Roller looks like it uses random hex strings, while Lulu's system 
happens to use consecutive integers. Unless hibernate requires The 
userID should be the only thing that needs to be stored within Roller - 
all the other details should be retrieved from the UserDirectory on 
demand. I don't know if hibernate needs a user table there just to 
satisfy foreign key constraints from other objects that are owned by a 
user, though.

User profile modification: It's definitely nice to abstract this at the 
API level, but I think it's also important to take it into account at 
the UI level. Some installations (e.g. Lulu) may want to require users 
to use their own UI's for editing settings such as password, locale, 
etc. It's worth considering a bit more about how this abstracting can 
happen at the UI layer as well. For example maybe it'd be good to allow 
the sysadmin to configure URLs for a login page, logout page, 
registration page, profile editing page, etc.) I think it's also 
important at the API level, a UserDirectory implementation is not 
required to implement the profile saving methods. The profile saving 
methods are really important only to the pieces of roller that tie in 
with the roller UI's to do that...

Authentication: Acegi looked fairly powerful & flexible for Lulu's 
needs. It seemed reasonably easy to implement a 
LuluAuthenticationProvider. I think the main hangup was more on the 
roller side - the implicit passing of RollerUserDetails between Acegi 
and CustomUserRegistry seems like a hack. I guess this is really more a 
problem on the user directory side of things than in the actual 
authentication functionality, though. If Acegi is going to continue to 
be an option, it needs to be made clear how acegi authentication 
providers are going to provide directory info to Roller.

On the authorization side of user management: this really seems to tie 
in with externalizing user permissions. I see global roles as no 
different from per-blog permissions or per-post permissions or 
per-comment permissions (etc. etc.) So...

On externalizing user permissions:

I'm really not big on the approach suggested - it doesn't seem general 
enough to allow tying in a wide range of authorization systems. From my 
perspective, I'd like to see something like the following:
    bool canExecuteOperation(Object subject, String operation, Object 
on_object, Object[] context);

         'subject' would identify the user who wants to carry out this 
particular action (e.g. 'Joe')
         'operation' would identify the action the user is trying to 
carry out (e.g. 'edit an existing comment')
         'on_object' would identify the object (if any) that the user is 
trying to execute the operation on (for example 'comment #1234')
         'context' could identify some objects that are relevant to the 
operation (for example 'blog #43' and 'blog post #432', because Joe is 
trying to edit his comment #1234 which was previously submitted to blog 
post #432 in blog #43)

The approach above allows for authorization implementations that have no 
way to answer the question "what operations is this user allowed to 
do?". The Lulu permissions manager is an example - although some of the 
yes/no authorization decision is driven by settings stored in the 
database, it is mostly code-driven and has to take into account 
situations such as moderated submissions, and book listings exclusive to 
one group.

At the same time, the approach above should still accommodates 
authorization implementations that offer an API similar to the one you 
proposed. This approach also allows the authorization system to define 
and manage roles internally, and decide how those roles map to specific 
operations.

I'm not sure about including permissions updates/editing in the API. 
This mainly goes back to the UI issues mentioned in my comments on 
authentication. Yes, Roller has UI to manage permissions, but that's 
only because it also has code to manage permissions. The UI for this 
feature should be abstracted along with the code, so that the 
RollerPermissionsEditingAPI is implemented by the 
RollerDefaultPermissionsImplementation code and only used by the 
RollerDefaultPermissionsImplementation UI/controller. I think it's 
fairly likely that plugging in new authorization systems will require 
plugging in new UI as well.

There are lots of pieces of Roller that I don't understand yet, which 
means a lot of this may be totally off. Please let me know what doesn't 
make sense :)

Best,
-- Elliot

Dave wrote:
> I'm working on two new proposals (see below) for externalizing user
> and permissions management, which is something that I need and others
> have requested, for example Elliot of Lulu.com and James Snell of IBM.
> These proposals are not complete, but I'd like to get some feedback
> now before I go too far into design.
>
> So, interested parties, please take a look and provide feedback. Does
> this meet our common requirements for externalized user profiles and
> permissions? What about the implementation? See any red flags for
> performance or scalability?