Generic Feedback Widget, Part V

“If at first you don’t succeed, you are running about average.”
M.H. Alderson

I looked at several different ways to solve my problem with the Generic Feedback Widget, but I couldn’t come up with anything that didn’t involve inactivating or altering the ACL that was at the heart of the issue.Finally, I settled on a plan that would at least involve minimally invasive alterations to the ACL. The plan was pretty simple: create an obscure User Preference and set it to true just before accessing the live_group_profile record, and then delete the preference as soon as the record was obtained. The alteration to the ACL, then, would be to check for that preference before applying the ACL. The updated version of the ACL script now looked like this:

if (gs.getPreference('snh.live.group.read.authorization') == 'true') {
	answer = true;
} else {
	var gr = new GlideRecord('live_group_member');
	gr.addQuery('member', GlideappLiveProfile().getID());
	gr.addQuery('group', current.sys_id);
	gr.addQuery('state', 'admin').addOrCondition('state', 'active');
	gr.query();
	answer = gr.next();
}

The first thing that we do is check for the preference, and if it’s there, then we bypass the original code; otherwise, things proceed as they always have. I don’t really like tinkering with stock components if I can avoid it, mainly because of the subsequent issues with patches and upgrades potentially skipping an upgrade of anything that you have touched. Still, this one seemed to be unavoidable if I wanted to salvage the original intent and still do what I wanted to do.

The next thing that I needed to do was to set the preference just before attempting the read operation, and then removing it as soon as I was done. That code turned out to look like this:

gs.getUser().setPreference('snh.live.group.read.authorization', 'true');
grp = new GlideRecord('live_group_profile');
grp.addQuery('table', table);
grp.addQuery('document', sys_id);
grp.query();
if (grp.next()) {
	groupId = grp.getValue('sys_id');
}
gs.getUser().setPreference('snh.live.group.read.authorization', null);

I ended up pulling that out of the widget and putting it into its own Script Include, mainly to tuck the specialized code away and out of sight. Anyway, it all sounded like a great plan and all I needed to do now was to test it out, so I did. And it failed. So much for my great plan.

It took a little digging, but I finally figured out that the ACL was not the only thing keeping people from outside the group from reading the group profile record. There are also a number of Business Rules that do pretty much the same thing. I spent a little time combing through all of those looking for ways to hack around them, and then finally decided that, for my purposes anyway, I really didn’t to be running any Business Rules at all. So I added one more line to my read script to turn off all of the Business Rules.

gs.getUser().setPreference('snh.live.group.read.authorization', 'true');
grp = new GlideRecord('live_group_profile');
grp.setWorkflow(false);
grp.addQuery('table', table);
grp.addQuery('document', sys_id);
grp.query();
if (grp.next()) {
	groupId = grp.getValue('sys_id');
}
gs.getUser().setPreference('snh.live.group.read.authorization', null);

That did it. Now, people who are not in the group can still read the group profile record, which is good, because you need the sys_id of that record to read all of the messages in the group, which is what we are using as feedback. The only thing that I have accommodated at this point is situations where a group profile record does not exist at all, and I have to create one.

But that’s an entirely different adventure

Generic Feedback Widget, Part IV

“For all sad words of tongue and pen, the saddest are these, ‘It might have been.'”
John Greenleaf Whittier

Well, it seemed like a good idea at the time. In fact, I was pretty proud of my Generic Feedback Widget once I had it pretty much all put together. I even felt so good about it that I went ahead and put out an Update Set. Then I started playing around with it while using other User accounts that did not have the admin role, and I realized that something was seriously wrong. In fact, nothing really worked at all. If you are not an admin or an existing member of a conversation, not only can you not enter any new feedback; you can’t even see the existing feedback that is already there. That’s not right!

It took be a little digging around to finally lay my hands on the source of the problem, but I found it. There is read ACL on the live_group_profile table that includes the following script:

var gr = new GlideRecord('live_group_member');
gr.addQuery('member', GlideappLiveProfile().getID());
gr.addQuery('group', current.sys_id);
gr.addQuery('state', 'admin').addOrCondition('state', 'active');
gr.query();
answer = gr.next();

The impact of that ACL is that you cannot read a record from the live_group_profile table unless you are an existing member of that group. Without access to the group profile, you cannot obtain the sys_id of the group to use in the query of the live_feed_message table to see all of the messages. And you cannot put yourself in the group if you can’t get the ID of the group to include on the live_group_member record you would need to create in order to make yourself a member. The bottom line to all of that is that, if you are not an admin (which overrides this ACL), you cannot see any messages related to the subject of the page and you cannot create any. That pretty much kills the entire basis of what I was trying to do.

The question now, is what, if anything, can be done about it. Obviously, I could simply deactivate that ACL and the problem would be solved, but that would also open up all kinds of other problems that that ACL was designed to avoid, so that’s not really a viable option. I could give up on my desire to leverage these existing tables and functions and just set up all new tables for this process with their own ACLs, but that seems like quite a bit more work than I normally care to undertake. Still, it seems as though there has got to be a way to leverage what I have already built without breaking things that are already in the product and not signing up for a major project. I need to figure out a way for non group members to read the group record without effectively killing that ACL for other purposes, or I am going to have to start all over with custom tables of my own design.

This should be interesting …