Over the years, I have developed several fw1 appli...
# fw1
t
Over the years, I have developed several fw1 applications that involve pretty granular permissions. Since a given permission might be required for a number of different section/action combinations, I’ve used various schemes for relating the fw1 context to permissions. But I’m curious as to how others might have dealt with the situation, if anyone is willing to share how they have attacked this.
w
did you use interceptors (AOP/1) to handle your permissions previously? i'd say that's a good starting point. alternatively, you could, as i have in the past, enforce per-method controller permissions by having explicit methods to validate them in controller method bodies like :
requireAdmin( session );
or
requireMember( session );
where perms are stored in the session
t
Thanks for the reply. I’ve used the latter method -sorta. The session does contain the permissions structure. But usually, I have implemented an authorization function which runs at the beginning of every request.. So in that case, my question would be more on the order of: how does an auth method determine the relationship between a request and a needed permission? Where/how is that relationship expressed?
w
give me a few mins and i'll track down some old code that demonstrates MY approach to this
t
Thanks. No rush.
w
Copy code
component accessors="true" {

    property settings; 
    property beanFactory;
    property common;
    property courseService;
    property moduleService;
    property emailService;
    property securityService;
	
	public any function init(fw) {
		variables.fw = fw; 
		return this;
	}
	
	public void function list(required struct rc) { 
		
		requireSysadmin( session );
		
		param name="rc.qp" default="1";
		param name="rc.so" default="al";
		param name="rc.sortdir" default="asc";	
		param name="<http://rc.ss|rc.ss>" default="";	
		
		var data = variables.courseService.list(
			qp=rc.qp,
			qnum=variables.settings.display.qnum,
			sort=rc.so,
			sortdir=rc.sortdir,
			ss=<http://rc.ss|rc.ss>,
			includehierarchy=true,
			cache=false
		);
		
		.....

	}
	
	public void function edit(required struct rc) {
		
		requireClientAdmin( session ); 
		
		param name="rc.id" default="0"; // when coming from list
		param name="rc.mode" default=""; // edit, blank when coming from list
		
		....
		
	}
	
	private void function requireSysadmin( required struct session ) {
		
		if(!arguments.session.isSysAdmin()) {
			variables.fw.redirect("error.unauthorized");
		}		
		
	}
	
	private void function requireClientAdmin( required struct session ) {
		
		if(!arguments.session.isClientAdmin() {
			variables.fw.redirect("error.unauthorized");
		}		
		
	}
	
	private void function requireAccountAdmin( required struct session ) {
		
		if(!arguments.session.isAccountAdmin()) {
			variables.fw.redirect("error.unauthorized");
		}		
		
	}

}
in that appabove, the roles cascaded, so if you were a sysadmin (during login, roles would be retrienved and stored in session) that means you automatically inherited client admin and account admin perms, etc
it's one way of doing it
the above controller code was intended to answer your question about how to marry roles with certain methods. just stick the line in really
there are more elaborate ways of doing the same thing, like annotating the methods with roles and inspecting the cfc when it's instantiated to sniff out the roles per method, but way more involved
t
Yeah, I see what you mean. Thanks. My situation is generally that the permissions are lots more granular - like ‘Can edit user permissions’ or ‘Can edit reports’ - so that an array of permissions would exist for each user. And because of the number of permissions, I’ve often created a ’hasPermission” method that examines the fw1 action and the permissions structure in the session. That requires a data structure somewhere that says “this action requires this permission,” and I was kinda wondering how others might handle that.
w
how many possible permissions exist?
and do you mind doing a db lookup each time to verify the user has permissions to execute a given controller function?
t
To your first question, it varies. In one application, there are currently 59 possible permissions. And to your second: certainly, storing the relationships of requests to permissions in the database is one solution. The other, which I’ve used with a smaller set of permissions, is to create an array of objects with paired permission and action which remains in memory. And of course, that could be stored either in a configuration file or created from database relationships. I’m not really looking for a solution. More just wondering if someone else has a better scheme.
w
understood. do you equate permissions with controller methods? that is, is action=user.edit equivalent to 'user edit permissions'?
t
Unfortunately, it’s not that simple. Lots of controller methods may require the same permission. Not at all one-to-one.
w
in the past i've found that complex user/role/permission evaluation usually requires a db lookup. you can avoid that by storing abbreviated 'permission masks' in the session to make it easy to validate a given action, but at the expense of some granularity since you don't want to bloat the crap out of the session. nothing you don't already know i'm sure
t
Yep. All the usual things I’ve dealt with. Thanks for the feedback.
w
like,
session.allowedActions = ["main.*","user.list","user.edit"]
so you can easily match the requested route to whether they can access it. but i think that can get unwieldy if you have too many possible variations