Selecting security profiles on the fly

My customer has a number of regions. Each region has it’s own security profile. eg a user in region 1 is not allowed to operate stuff in region 2.

The normal way to handle this is to create a different project for each region.

In this case however, the projects would be the same. The user will open a navigation project and pick an area from there. This will redirect the user to a new project. The data that is used to populate the screens is all database driven. ie: a global can be set when the project is started that the project uses to display data.

I’d rather not have a bunch of identical projects to maintain. Is there some way I can programmatically pick an authentication profile to verify a user against when the second project is opened?

Are your projects hosted on the same FactoryPMI Gateway or different ones? If different, are they at geographically separate locations?

I recommend using separate FactoryPMI [del]groups[/del] roles to give access to: Region 1, Region 2, etc. Users could have permissions to one, all, none, or any combination. As long as the credentials match, this works across gateways with retargeting. That said, in most cases you should shoot for the “one database” model.

If all the users have accounts on a Windows domain, you could use Active Directory to authenticate.

Alternatively, you could use database authentication to maintain the users and groups.

A lot depends on your architecture here.

It’s one gateway with hybrid authentication.

A single corporate A/D for all users.

I could create regional groups but then my security code becomes a lot more complex.

Ideally, it would be great if I could pass the security profile to use as a parameter to the retarget function.

As a close second the ability to call fpmi.secutity.authenticationCurrentUser(profile_to_use)

Another solution may be to create a security project for each profile that just retargets to the common project. The common project would check that it was started with the correct globals set and that it was retargeted from one of the security projects and exits if not.

A little more complex but I still end up with one project that does the real work rather than a bunch of identical clones. :scratch:

edit:
but then I would lose the role information :sigh:

Creating regional groups may be easier than you think. All you have to do is give everyone a region role in addition to their other roles and add this to any button press that navigates to a different region:

if "region1" in fpmi.security.getRolse(): fpmi.nav.openWindow("Region One")
If that seems like too much, you could make every region jump go to a single nav page without that code and just make sure that nav page has it for each button.

For more info on FactoryPMI security (with examples), see the user manual and go to Technical Reference->Jython->Built In Modules->fpmi.security.

Robert, I know I can create regional groups. That isn’t a problem. The problem with region groups is when a user operates a control I do a check to see if they are allowed to. Right now that check looks like this:

def ok_to_operate():
    import fpmi
    if 'FPMIAdministrator'  in fpmi.security.getRoles() or 'Operator' in fpmi.security.getRoles():
        return 1
    else:
        fpmi.gui.errorBox('Insufficient security privileges.')
        return 0

If I created groups for each region and used a single project then I would then have to change this code to be aware of what region was currently been looked at and then check against the correct groups for that region. Yes it can be done but is messes up a simple clean function.

Call this option 4 :wink:

ps I’ve already looked in the manual for the authenticateCurrentUser() function. That’s why I started this thread. :laughing:

OK, I get it! you have a second project that has a global variable to tell it what region it is looking at. Haha, it all makes sense now.

No, the auth profiles are static. However, the SQL query you use to access it is not (in a database driven authentication profile). There is a Query Configuration (expert) section when you edit your auth profile queries. Just store the username/target project in the db somewhere and then call the retarget. Use the Authentication Query and User's Roles Query spots in the authentication profile to call a stored procedure that uses the $username$ to check what authentication tables to use.

Presto! You just have to manage a username/project table and have a case in the stored procedure that accounts for a user not being in that table yet. And you can't use the AD profile types...

If you want to use AD, you can create copies of each roll for each region and concatinate them from the user/project table. Something like:

def ok_to_operate(): import fpmi username = fpmi.security.getUsername() region = fpmi.db.runScalarQuery("SELECT region FROM user_region_table WHERE username = '%s'" %username) operatorRole = '%sOperator' %region if 'FPMIAdministrator' in fpmi.security.getRoles() or operatorRole in fpmi.security.getRoles(): return 1 else: fpmi.gui.errorBox('Insufficient security privileges.') return 0

[quote=“Robert”]It’s one gateway with hybrid authentication.

A single corporate A/D for all users.

I could create regional groups but then my security code becomes a lot more complex[/quote]
I don’t understand what is complicating your security setup. How many regions are there? Within each region, how many security groups/settings are possible? Could you describe the differences in what you do differently between regions?

It should be simple to create Active Directory OUs. Manage your users there. You then deal with FactoryPMI groups, which based on your first post, determine what database driven properties “set the region”. You should be able to use a single AD authentication profile between all projects.

I think there’s something fundamentally simple that you’re missing about how AD works from the FPMI side…or a very complicated factor of your setup that I’m missing.

[quote=“Robert”]
If I created groups for each region and used a single project then I would then have to change this code to be aware of what region was currently been looked at and then check against the correct groups for that region. Yes it can be done but is messes up a simple clean function.
[/quote]You just write a second clean function that determines what region(s) the operator is a member of. Then the code does 2 checks - do I have permissions to perform said action and am I a member of the requested region. Obviously you’ll need to store more granularity if users can have different permission sets across regions, but it’s still pretty simple (region1Admin, region1Operator, region2Admin,…).

A lot to think about. Thanks guys.

The customer already has a number of FPMI projects. They also have 1000's of employees. A/D is a must and I (nor my direct client) have any control over it. (I've being told the hybrid model was created at our request because of this :wink: )

Up till now we have being controlling permissions with a separate profile for each project. It was my intention to maintain that setup as the customer has procedures in place to deal with that setup. I could go the database route, but then I would have to create maintenance screens for the customer. Not a lot of extra work, but now the customer has two places to maintain user profiles. (unless I can modify an authentication profile from code :scratch: :study: )

It sound's like I'll have to do some database stuff regardless.

Customer's IT is complicating my security setup
Currently there are 4 regions. As the system grows, and depending on the granularity the customer wants, there can be upwards of 40. The only difference is security.

That's most likely what I'll do.

In the mean time I'll create some more feature requests :slight_smile:

Yeah, I really think that regional roles are the way to go here. I think that the authentication code would be just as graceful if it properly abstracted out into a project scripting module.

I agree. Just make Windows groups that correspond to the FactoryPMI role names for each region. Permissions are all managed by IT within Active Directory (which can be delegated if they see fit).

After discussing it with the customer, we’ve decided to create regional roles in a single project/profile

Thanks everyone for your ideas