What steps should I take to allow a user on my team to have access to only a subset of a large data file. This file is a list of all recorded time on hundreds of projects. I want the user to only be able to Find/Create data with his user ID.
You can handle this by means of the Privilege Set associated with someone's login account. The nice thing is that Filemaker effectively makes records unfindable if you're not allowed to see them.
- userID is a field in table RecordedTime
- the user ID is also in a global variable $$userID, which is set at login (startup script)
- go to Manage>Security..., tab Privilege sets
- create a new Privilege Set, let's call it 'User restricted'
- assign general privileges, like some access to layouts, scripts, printing etc., appropriate for this type of end user
- click the popup menu next to Records: (top left), choose Custom Privileges...
- select the RecordedTime table
- on the bottom there's a popup menu under 'View', select option 'Limited...'
- create a calculation that establishes the restriction, e.g.
RecordedTime::userID = $$userID
- make sure the calculation is evaluated from the right context, in this case RecordedTime, otherwise there will never be a match resulting in 'true'.
- Assign the new privilege set to any account that needs it.
This was very helpful. Thank you.
However, after setting this up, when I open the file under that specified user all the data that he should not be able to see is not invisible, it is all present but each field says <No Access>. Can I make the restricted records invisible?
That final level of Record Level Access (RLA) control is usually implemented with scripting. I have done it by taking users to a pre-defined set of records they are allowed to see, such as a Find on user ID.
You can also customize the Find command to run a script which takes their request but appends the info of their user ID as a final embedded option when they execute the Find, so that records without their ID are not included.
You do have to control things such as the Show All and Show Omitted processes as well to completely hide the <No Access> records from users with restricted access.
It would be really nice if FM implemented a record not even visible option for RLA controls. The <No Access> info does the trick of hiding restricted data, just not very elegantly when used alone.
Stephen is correct. In order to suppress the somewhat perplexing <No Access> display, you'll need to use scripting. In addition to his good suggestions, may I offer the use of an OnRecordLoad Script Trigger that omits the current record if the user doesn't have access. This can be effective to prevent users from scrolling into records they shouldn't see.
P. S. And I also agree with Stephen. It would be nice if FMI would implement a way to do that automatically.
Stephen Huston wrote: You can also customize the Find command to run a script which takes their request but appends the info of their user ID as a final embedded option when they execute the Find, so that records without their ID are not included.
Stephen Huston wrote:
There is no need for this. Any find will automatically omit records to which user has no access (as already explained in the first reply by Peter). OTOH, you need to deprive your users of the opportunity to use the Show All Records command.
"OTOH, you need to deprive your users of the opportunity to use the Show All Records command."
and I suppose the "Show Omitted"
Omit on RecordLoad:
Curious if one would get screen flashing etc. on Win machines if a large set is found.
On the question about OnRecordLoad - are you thinking if you're in a List or Table View?
If so, I'd say try it and see. I've never thought to try it in those views; been mostly interested in Form View for that application. As has been pointed out, performing a Find automatically removes any record to which the user doesn't have access, and if you trap Show All and Show Omitted ... well, it might not matter.
usbc wrote: and I suppose the "Show Omitted"
Indeed - thanks for catching that.
usbc wrote: Omit on RecordLoad:
That would be too late if you are in List or Table view. It would also mess up the record count.
Actually, FM displaying records you're not allowed to see anyway, tagged <no access> or whatever, or even the overall total record count, is 'almost' a bug IMHO. Think of a mail server: are you ever interested in the total number of e-mails your mail server has handled today? No thanks, please only the ones with my name on them, that I haven't received already. Keeping track of the total number of records in a database may be temporarily useful for a database administrator, or someone doing a conversion, but never to an end user. The Find All (and Show Omitted) command should function like any other Find: do not display what you're not supposed to see anyway. Has this been submitted as a feature request?
Of course, we have tools to solve this: just capture menu/keyboard commands like Find All/cmd-J using Custom Menus, and replace them with scripted Finds. Still, it feels like a workaround that shouldn't be necessary. Omitting records in an OnRecordLoad script is ugly. In list or table view, they wil visibly disappear one by one.
If instead your privilege set is set with a realtionship rather than you finding and omitting records, you can restrict your user from only ever finding his records... including in any record count.
All this find and omit is less secure and make the job a lot bigger by needing to trap for all the possible errors.
I'd tend to agree.
But what it "should" do, versus what it does do ... well, we have to work with the latter.
Embed the calculation as a relational predicate?
If the condition ifor seeing the files is that thieir UserID (or account name) matches related records only... then that is all the user will ever see... his or her own records via that relationship.
Another thing you can do if you are going the find-omit route is customise the Show all Records menu item and have it perform a partial find based on the UserID instead of it's standard behaviour.
Been thinking about this one. But I'm a little confused. How do you set up the relationship so this works? Through a single-record table and a portal? Or do you try to set up a one-to-one relationship and keep the two tables synchronized?
I don't think I'm getting this ...
One approach is to :
1. Have an account ... say John... who belongs to the staff privilege set.
2. Have 2 tables for elegance but I think you can get away with only one...
Yes you can have a global field which is populated with the Account name John and have records relate to that...
But you could have no actual relationship and have the staff privilege set only see records where Get(accountname)=Records::field.
The relationship helps because a new record will automatically have the value in field populated with John.
But you could set field to auto-enter the Get(accountname).
The school bus is calling.
I'll check if this makes sense again later...
This problem has been there for 10 years, there are several way to go around and all seems ugly, if you don't want to see the ugly, maybe you can use Conditional formatting to make the <No Access> disappear, hope it works.
This is about one user access a subset of date, how about several user want to access a subset of data, let's say, I have several store, and each store have several stuff work there and they may input their sales data and they need to access only the data from their own store but not other store's data.
try to write a script with the following comand:
Perform find [Restore]
Find records when: any field
can solve your problem.
But it will be a little bit slow if the record set is large.
PS: What I am facing the problem is more difficult, anyone if interest please search my post!
Retrieving data ...