StrataFrame Forum

Dynamically setting user roles?

http://forum.strataframe.net/Topic3970.aspx

By Greg McGuffey - 10/30/2006

The application I am considering StrataFrame for is project based. I.e. the data is all related to a project and the users role is based on project. On one project a user might be the project manager, having more permissions and on another she might be a reader, only able to view data, no edit/add/delete it. Is this possible using StrataFrames security?



As I see it, the user would be authenticated, then I would need to see what project they are working on and then change their role. This is probably covered in the helf file, but I'm running out of time to evaluate StrataFrame :-/



Thanks for you help!
By Trent L. Taylor - 10/30/2006

Is this possible using StrataFrames security?

This is definitely possible.  There are several ways to go about this.  The easiest would be to create two separate security projects.  One for project A and another for project B.  This way the two do not have to co-exist.  However, if you would prefer to move roles and permissions around, this is possible.  Some of this may be resolved for you when you look through the security and get a little more in depth and see how it ties into the application when you distribute your application. 

Another option, for example, is to do what I mentioned above with the two different security projects.  But if you are using the same application assemblies (same EXE) you could just swap the security database key based on which project they are running.  This would just entail that you have the security data in two separate databases and you just point security to which database you want to use based on the project.

I would need more information to give you a solid recommendation, but there are a number of ways to "skin the cat." Smile

By Greg McGuffey - 10/30/2006

I don't see how multiple security projects would help. First, there aren't two, there are many (n). Second, the projects are time limited, with new ones all the time. Wouldn't this mean creating the permissions as well as roles in each project? This seems like it would be a huge duplication of effort.



However, you say I can reassign a user's role on the fly, and I assume maybe permission also. Could you provide some sample code, so I know that objects and methods I am to use?



Thanks!
By Trent L. Taylor - 10/30/2006

Based on your previous post, you used the term "project" which generally entails completely different assemblies or applications...thus the different security projects.  Before I try to give you a sample, I guess it would be best if I understood what you were trying to accomplish.  Is the user whose account you want to change going to be going into the same application or different applications?  Are the two applications related at all, other than trying to reuse the security permissions and roles?
By Greg McGuffey - 10/30/2006

Ah! I see the confusion. Not projects at all in terms of development, rather the client I'm building the app for has projects. I'm building an app to help them consult with many clients on many projects. The app alwasy does the same thing, just on many different consulting projects. One app, one exe used on many projects.



E.g. Contractor 1 (a consultant) is on project A at client One. He is the project manager there.

However, on project B, at Client Two he is just a reader, providing QA for the project.

And on project C, at client Three, he has no access at all.



I will provide a means for the user (Contrator 1 in example above) to switch between any of the projects they are assigned. When a project is selected, their role for that project will be set. (Based on a table that maps users to projects with certain roles (or maybe role sets...not sure until I know how this works a bit better)).



Does that make more sense?
By Trent L. Taylor - 10/30/2006

Yes...that makes much more sense...What I would do in this case is create a dynamic permission key that is associated with each project.  All of the SF business object classes are in the MicroFour.StrataFrame.Security.BusinessObjects namespace and you can use them just as though you were writing your own SecurityDialog form. 

So when a new project is created I would create a new permission key:

Dim loPermission As New MicroFour.StrataFrame.Security.BusinessObjects.SFSPermissionsBO()

'-- Create a dynamic permission key
loPermission.Add()
loPermission.pm_Key = "Project 1 Key"
loPermission.pm_Description = "Dynamic permission key created at run-time."
loPermission.pm_BlockedAction = DeniedActions.Message
loPermission.pm_Category = "Client Projects"

'-- Save the permission key
loPermission.Save()

After the key exists, you can dynamically add this key to the user or modify it through the standard SecurityDialog window that comes with the framework.

Then when you need to test on the security key you would just do this:

Select Case SecurityBasics.CurrentUser.GetPermission("Project 1 Key").Action
            Case PermissionAction.Deny
            Case PermissionAction.Grant
            Case PermissionAction.ReadOnly
        End Select

Does that make sense?

By Greg McGuffey - 10/30/2006

Almost. BigGrin



This seems to me that what you just suggested if there are different permissions for each project. That is cool, but not what I was needing.



The permissions are the same across projects. I.e. I might define the following permssions:



ProjectSetup - Allows project managers to setup project defaults

ProcessEditor - allows the user to edit processes (this is data managed by the app)

ManageMyProjects - allows user to change projects



They I might define the following roles:



ProjectManager - would have the ProjectSetup permission, ProcessEditor and ManageMyProjects permissions

ProjectEditor - would have the ProcessEditor and ManageMyProjects permissions

MyProjects - would have ManageMyProjects permission





Now, when Contractor 1 is working on Project A, I want to assign him the ProjectManager role and when working on Project B, the ProjectEditor role and on Project C, only the MyProjects role.



Permissions would be constant, based on feature set. Roles would be more fluid, but defined across all projects. User's assignment to a role would be based on which project they were currenlty working on.



So, I really need to have the ability to dynamically assign the current user to a specific role, one that is already defined for the application.
By StrataFrame Team - 10/30/2006

You will have to keep track of the roles assigned to each users on a per-project basis, then, right before the user logs into the system, you will need to change them to the appropriate role within the SFSUsersXRoles table so that they will be assigned the proper permissions.

So, essentially, you would be able to use the SecurityDialog to create the users and roles, and assign the permissions to the roles, but you will need your own editor to assign users to the roles for each project.  Then add/remove records to set the user to the appropriate role before the LoggedInUser.SetLoggedInUser() method is executed.

By Greg McGuffey - 10/30/2006

Yep, I was planning on tracking the user/role/project myself and on having an editor to assign users to roles based on project, so all of that is expected.



However, I will need to authenticate them, before I know who they are and can therefore determine what project they are working on (I also keep track of the last project they worked on, so I know what project to log them into at startup). Also, I will need to allow them to switch projects, without authenticating again. So, can I call SetLoggedInUser() separate from authentication? And can I call it independant of any authentication? I.e. it seems that what I need to do is authenticate the user, determine project and then role, update the SFUserXRoles table with the appropriate role for the project, the call SetLoggedInUser(). If I need to change projects, I would simply skip the authenticate step, but everything else would be the same, right?



Thanks for you quick replies to this.
By Greg McGuffey - 11/1/2006

OK, not so quick reply Ermm



I've been trying to figure out this stuff and it is a bit clearer, but I still have no idea how to actually do it. Basically I would like to do four things:



1. authenticate user (using SF security tables), look up there default project (in an app table, I can figure this out), lookup role they are assigned for this project (again my app tables, and I can do this), assign them that role (something about updating SFSXUserRoles table), then maybe some other action that makes this role take affect(??).



2. Allow the user to switch projects. They are already authenticated, just need to provide them a list of projects (this I can do), they pick one, lookup the role for that project, then back to assigning them that role and some action to make it take effect.



3. Allow user to logoff, then log back in, of course, this would include all the project stuff again



4. Lock app, so they have to reauthenticate to continue. Not sure how any open forms are handled here at all. Any info would be helpful as well as info on how to implement.



Sorry for being such a pest, but I'm on a tight schedule to see if this will work for this project (in this case, I'm talking about my own dev project, not one of the projects within the app...Hehe
By Trent L. Taylor - 11/1/2006

OK, not so quick reply

I don't know what happened here because I remember Ben responding to this as I walked out of the office the other day.  So I am sorry for any trouble.  He must have accidentally closed before posting or something.

assign them that role (something about updating SFSXUserRoles table), then maybe some other action that makes this role take affect(??).

Yes.  You are basically looking at being your own SecurityDialog.  In essence you will need to manipulate the tables to move the permissions and/or roles to the appropriate user for the appropriate "application project" (referring to projects within your application).  You are on the right track here.  This is obviously a little more advanced than standard use, but is possible all the same.  One thing that might help you visualize the tables a little better is in the Security Help file:

Defining Security within the Appplication -> Deploying Security Data

Just go to the bottom and you will see some screen shots of the tables with data. One other topic that may help is the hierarchy of the permissions.  For example, if you have a role with a permission defined, it can be overridden at the user level.  Obviously if the user permissions are left alone and you go solely off of a role here, you only have to move one record around.  If you go to the user individual permissions level you will have to move the number of records that pertain to your project settings.  Just a tip Smile

Security Maintenance -> Permissions -> Permission Hierarchy

Allow the user to switch projects. They are already authenticated, just need to provide them a list of projects (this I can do), they pick one, lookup the role for that project, then back to assigning them that role and some action to make it take effect.

You can just manually re-login the user to get the permissions up to date.

MicroFour.StrataFrame.Security.Login.SetLoggedInUser(...)

You can learn more about this under the web applications authentication. Defining Security within the Application -> Web Applications -> Authenticating Users

Allow user to logoff, then log back in, of course, this would include all the project stuff again

Not much to say here other than yes.  Once you change the permissions the will take effect the next time they log on.

Lock app, so they have to reauthenticate to continue. Not sure how any open forms are handled here at all. Any info would be helpful as well as info on how to implement.

This is called session locking and is an easy to implement feature.  To learn more about this, look in the help docs under: Security within the Application -> Session Locking

To implement session locking, look at the article: Defining Security within the Application -> Adding Security to an Existing Application

Go down to 5c and you will see how to start the session monitoring.

By Greg McGuffey - 11/1/2006

I don't know what happened here because I remember Ben responding to this as I walked out of the office the other day. So I am sorry for any trouble. He must have accidentally closed before posting or something.




Figured something like that must have happened. No worries. You guys have been very good about being responsive and very helpful. And when this did fall through the cracks, you got right back on it. Excellent.





You are basically looking at being your own SecurityDialog




Is the SecurityDialog the form that allows you to manage users/roles/permissions? I'd still use this to create roles, users and set permissions for roles, but use my own to define which role a user gets on any specific app project. Right?



What I'm still really unclear about is what exactly happens in the ShowLoginAndInitMainForm sub in AppMain.vb. There is one line of code there that calls the logon form, authenticates the user, sets that user as the current user (unless they cancel, then it closes the app), then opens the main form. Seems like I will need to take control of this so I can insert the project related stuff. Will I need to user my own login form? I assume this work doesn't happen in a form, right?



I think I can figure out how to manipulate the permission (I take a look at the help topic you noted), but I don't understand what I'd have to do to end up with a logged on user if I have to do it myself.



If you go to the user individual permissions level you will have to move the number of records that pertain to your project settings. Just a tip Smile




Good tip Wink



I'll take a look at all the info you indicated also.
By Greg McGuffey - 11/1/2006

OK, first question about updating the SFSUserXRoles table. There is a ur_CreatedBy and ur_CreatedAt fields, both required. Do I need to set values for these? I'd use the SFSUserXRolesBO to do this, I assume. If so, who would be the user? The security user? How would I use that logon to do this work?



First of many questions, I'm sure...
By Trent L. Taylor - 11/1/2006

ur_CreatedBy and ur_CreatedAt fields

Leave these fields alone..they will be automatically set through the default values of the BO.

I'd use the SFSUserXRolesBO to do this, I assume. If so, who would be the user? The security user? How would I use that logon to do this work?

You can leave these alone if you would like.  However, you can set these to the user PK value associated with your administrator user.  This is generally a -1 for the user PK.

By Greg McGuffey - 11/1/2006

[quote]You can learn more about this under the web applications authentication. Defining Security within the Application -> Web Applications -> Authenticating Users[\quote]



My help file doesn't have this section or I couldn't find it (in either the framework help or the security help). I searched the security help file for 'web' and there were no results. You have a newer help file than I do perhaps?
By Trent L. Taylor - 11/1/2006

I am not sure when you last downloaded...but if you get the latest version the helps docs are updated.  Just to save a little time I attached the CHM to this post.
By Greg McGuffey - 11/1/2006

Thanks for the quick replies.



I was hoping that was the case regarding the CreatedBy and CreatedAt fields. BigGrin



I have 1.5.0. I haven't d/l or installed the newest version (1.5.1). I will attempt to get that done ASAP. The new help file is good. I'm reading it now...
By Trent L. Taylor - 11/1/2006

There are a number of enhancements and updates to the framework in 1.5.1 so I recommend doing this when you get the chance.
By Greg McGuffey - 11/1/2006

Will do. The new help file really helped. You didn't directly answer this question, but I'm getting very close to understanding how to do this:



What I'm still really unclear about is what exactly happens in the ShowLoginAndInitMainForm sub in AppMain.vb. There is one line of code there that calls the logon form, authenticates the user, sets that user as the current user (unless they cancel, then it closes the app), then opens the main form. Seems like I will need to take control of this so I can insert the project related stuff. Will I need to user my own login form? I assume this work doesn't happen in a form, right?




So, I get how to manually do this. The steps would be something like:



1. Get user credentials (user name and password) (question below about this)

2. Authenticate user using AuthenticateUser()

3. Using the us_pk property of the returned SFSUserBO, I would lookup the users default project in my own table and get the pk for the role to use with this project (using BO for this table of course)

4. Using the SFSUserXRolesBO, I would update the existing role for the user

5. Make this user the current user by calling SetLoggedInUser()

6. Show the main form if they didn't cancel out



Did I miss anything?



Now, a question about using an SF Login Form. I'm assuming I wouldn't use this at all, because it is part of the Login class (or rather it appears to be used by this class) and as such, I wouldn't have the control I need, correct? Or another way to ask the question, would the SF Login form be of any use to me here?
By Trent L. Taylor - 11/1/2006

Did I miss anything?

I think you're good Smile

Or another way to ask the question, would the SF Login form be of any use to me here?

If you download the latest 1.5.1 build, there is a template to create a custom login form.  You will want to use this as it ties into session locking, etc.  When you create the template, you will see that all of the required code is already in the form.  You can place your code to do your "permission swapping" in the click of the OK button.  Basically you will manually call the AuthenticateUser() to make sure the entered text is valid...if so, place your code to swap your permissions.  Then after you have done that, call the Me.OnAttemptLogin so that all of the remaining logic will remain in place.

I know that you can make this work...and I am pretty confident the instructions I gave you will work...but if not, let me know and we will address the issues one at a time.