Finding a Channel's Audience
Introduction
At Clayton State, we have created a channel that displays the top 5 most recently created, and recently modified channels. During this process we discovered that much of the channel information is stored in LDAP (and thus is why it is so mysterious to find).
Our channel has a few shortcomings, one of which is that all users see the same top 5 newly created, or updated channels, regardless of the channel's audience. This means that if we wanted to honor the Portal's permission ...uh... structure, then we had to do some digging.
Just to show you where this is going, my test channel's audience can be described as "((role=public) AND (role=admin OR login=jwallom))".
Prerequisites
- Portal database access, and SQL software
- LDAP access (and preferably an LDAP browser)
Getting the Channel's Primary Key
Start in UP_CHANNEL. This is a DB table that will show a listing of all channels, Targeted Content Channels (TCC hereout), or other. Locating the channel by name would be easy except that that this too is stored in LDAP for TCCs. That is a topic for another day.
Once you have located the channel, you will need to reference the CHAN_ID column of your record. This serves as the primary key for your channel. (497 in my case)
Locating the audience
Once you have the key, fire up an LDAP browser (such as this one), and navigate to the following DN:
ou=AssetMetaData,o=####.edu,o=cp
The "#" symbol should be substituted for your institution's domain. In our case, we are "clayton". Do a search from this directory ("View" -> "Search"), by building a filter that looks like this:
cn=PolicyData:UP_FRAMEWORK\\\:SUBSCRIBE\\\:CHAN_ID.###*
Substitute in your CHAN_ID number in place of the ### from the previous section. Also, end your query with a "*" to get act as a wildcard for the remainder of the entry. This will locate the LDAP entry that describes audience for your channel.
If your DN reads something like:
PolicyData:UP_FRAMEWORK\:SUBSCRIBE\:CHAN_ID.497\:\:1174\:3.sct.public
then you should pat yourself on the back for not using silly filter groups. You have just saved yourself a LOT of work. The key section of information in this string is at the very end where it reads "sct.public". This means the public group. In other words, this channel has no refined audience - everyone is able to view it.
If it reads "sct.Students", for example, then the role "Students" would be the only group able to subscribe to this channel.
Filter Groups
If instead, your ending string reads something like:
PolicyData:UP_FRAMEWORK\:SUBSCRIBE\:CHAN_ID.497\:\:1174\:3.filter.198
then the rabbit hole goes much deeper. You have created a more complex audience definition, and the Portal has converted this to a filter group. Keep the filter group number (198) in my case in mind for the next step.
Filter Group Details
Go back to your database and view the table UP_FILTER_GROUP and select all where the group_id equals your filter group id from the previous step.
In my case, I have a record that reads, "ENTITY_TYPE_ID = 3", and "OPERATOR_ID = 1". The ENTITY_TYPE_ID column is a foreign key to the UP_ENTITY_TYPE.ENTITY_TYPE_ID column. It describes what object this filter group represents. In my case, a "3" means it is a group. The OPERATOR_ID column is a foreign key to the column UP_FILTER_GROUP_OPERATOR_TYPE.OPERATOR_ID. In my case, a value of "1" translates into the "AND" operator. So this entry tell me that I have "AND role=..." in my filter group. We will find out what group next.
Run another query against UP_FILTER_GROUP_MEMBERSHIP selecting all where the group_id is equal to the filter group id from earlier (198 for me). You may get multiple records back on this one, take it a piece at a time.
My first record reports MEMBER_SERVICE = "sct", and MEMBER_KEY = "public". This is part of my filter group definition. The operator type from earlier lets me know the relation ship between this filter group entry and the next row ("AND"). So now I know part of the audience is "(role=public AND (...))". I think that this will be the same for everything, since public is the most general audience definition.
The next row has MEMBER_SERVICE = "filter", and MEMBER_KEY = "3822". This lets me know that I have another filter group inside my filter group. This is because I switched operators. Each filter group can only handle one operator, and to use a combination of "AND", and "OR" operators, it creates them as nested filter groups. This is why the interface inside the Portal is clear as mud!
Now, if you want to explore this nested filter group, you want to repeat the steps above, using the GROUP_ID of this new row (3822) in my case, as the new filter group id. I will select all from UP_FILTER_GROUP, and from UP_FILTER_GROUP_MEMBERSHIP where the group_id equals 3822. Running this returns two more records, half of which we have already discussed the format of. At this point, I now know the following audience: "((role=public) AND (role=admin OR ...))". We are getting close...
Pags
Yes, you read correctly - pags. What it means, I have no idea (nor care at this point). My last record from the previous step returned a MEMBER_SERVICE = "pags", and a MEMBER_KEY of "UPD_23".
Lets run a new query on the table UP_PAGS_TEST, selecting all where TEST_ID equals the numerical portion of the MEMBER_KEY value (23 in my case). A record returns with my test condition. The TEST_ATTRIBUTE_NAME is "urn:sungardhe:dir:loginId", and my TEST_CLASS is "org.jasig.portal.groups.pags.testers.StringEqualsTester", and my TEST_VALUE is "jwallom". Looking at this, we can determine that the loginid must be equal to "jwallom". This is consistent with my audience definition at the beginning of this article. So now, I know my audience is "((role=public) AND (role=admin OR login=jwallom))"
Conclusion
I hope that this sheds some light in a very dark corner of the Portal's structure. The programming conventions are proprietary to the point of near obfuscation, but if you dig deep enough, you can connect the dots. Now, let me conclude with pulling in the original scenario in which you would want to use this wonderful information:
I can now take our TCC channel, and only display the top 5 channels to a user based on who specifically they are. Because they only see what they should be able to we are enforcing our security while keeping it DRY.
Also, this can be a launching platform (for us it is anyways) to integrate in one-click adding of a channel. Since you already have the CHAN_ID from our database query, you can mimic the "Content Layout" functionality of the Portal, using the excellent guides from Brian Ferris, and others.
Additionally, you can let a user browse channels by searching for keywords, categories, tags, descriptions, etc then filter the results based on the user logged accessing the information.
Enjoy!
Update: 12/12 @ 9:11 I have attached sample code with documentation to hopefully save you some time!

Recent comments
15 hours 26 min ago
17 hours 11 min ago
21 hours 44 min ago
22 hours 46 min ago
1 day 16 hours ago
1 day 17 hours ago
1 day 18 hours ago
1 day 18 hours ago
1 day 20 hours ago
2 days 26 min ago