Wednesday, August 27, 2008

BEA Publisher is finally gone

I hated this piece of software. It did a job that everyone wanted it to, but it only did it at 80%. That means I had to explain why it didnt meet this or meet that. Finally Oracle has made the decision to kill the POS. Everything will now be under UCM. YESSSSS!!

Monday, July 02, 2007

Security vulnerability in the Portal

Everyone,
I found this security hole about 2 years ago. BEA mentioned they were going to fix it, but they have not yet done it. I would like to show you what this hole is, and then how to fix it.

What it is: Using the opener link in 5.x or the normal navigation in 6x you have the ability to view the "edit" page of any community regardless of security. This means that as a guest user you can view the security on a community, and see all of the users who have access. A hacker can use these usernames to then try and hack into your site. Lets take a look at the opener object for 5x. It takes the following parameters: space, control, in_hi_ClassID, in_hi_ObjectID, and in_hi_OpenerMode. All that you need to do is put in parame space=Opener&control=OpenObject&in_hi_ClassID=512&in_hi_ObjectID=(target obj id)&in_hi_OpenerMode=1&

Here is a picture of what it could look like:

That is not so bad, but look at what else I can see when i click security and one of the groups (I scratched out the names to protect the innocent :P):


Now you can clearly see how dangerous this can be.

How to fix it:
This is easier than you think. See the BEA documents on help with implimenting these changes.
in 5x make sure this is in your ObjEditorModel file under com.plumtree.portaluiinfrastructure.editor. In the if block under "else if (EditorStartControl.EDITOR_START_FLAG_EDIT == m_nEditorType)" you need to have an entry that looks like:

default:
bObjectIsAccessible = m_Session.GetObjectManagers(m_nClassID)
.IsObjectAccessible(m_nObjectID,
m_Session.GetSessionInfo().GetCurrentUserID(),
PT_ACCESS_LEVELS.PT_ACCESS_LEVEL_EDIT);

break;


6x seems to already have it in there. I think this was BEA's attempt at fixing the issue. There is one more thing that is needed to fully fix this though. A PEI. This is for 5x and 6x:

Create a new PEI for IOpenerActions. In the method OnBeforeOpen put this in:
public Redirect OnBeforeOpen(int _nClassID, int _nObjectID, java.lang.String _strClassKey,
XPHashtable _htQSArguments, Redirect _rRedirect, AActivitySpace _asCurrentSpace, java.lang.Object _userSession)
{
IPTSession _ptUserSession = (IPTSession) _userSession;
// check for creating a new one
if ((_nObjectID == -1))
return null;

// we want to check for the security of the user and such.
// a return of null is to go as scheduled.
XPHashtable formData = _asCurrentSpace.GetCurrentFormData();

String sModes[] = null;
sModes = (String[]) formData.GetElement("in_hi_OpenerMode");
if (sModes == null || sModes.length == 0)
sModes = (String[]) formData.GetElement("mode");

String sMode = null;
try {
// in case some one puts in a bad opener mode such as 6
if ((Integer.parseInt(sModes[0]) > 1)
&& (Integer.parseInt(sModes[0]) <= 3))
{
// no need to check for this stuff
return null;
}
else
{
sMode = "1";
}
}
catch (Exception err)
{
sMode = "1";
}

boolean hasAccess = CheckAccessLevel(_nClassID, _nObjectID, PT_ACCESS_LEVELS.PT_ACCESS_LEVEL_EDIT, (IPTSession) _userSession);

if (hasAccess)
return null;

// create the redirect except send it as mode 2
log.Info("possible hack detected for user: "
+ _ptUserSession.GetUser().GetName());

String sRedirect = PTOpenerLinks.GetOpenerURLOpenObjID(_nClassID, _nObjectID, 2,_asCurrentSpace);
Redirect redirect = new Redirect();
redirect.SetLinkToExternalURL(sRedirect);
return redirect;

}


Now add a new private function:
private boolean CheckAccessLevel(int classID, int objectID, int accessLevel, IPTSession session)
{
boolean bObjectIsAccessible = false;

// JF- First we check the edit access
switch (classID)
{
case PT_CLASSIDS.PT_CATALOGFOLDER_ID:
case PT_CLASSIDS.PT_CATALOGCARD_ID:
bObjectIsAccessible = session.GetCatalog().IsCatalogObjectAccessible(objectID,
objectID, accessLevel);

break;

case PT_CLASSIDS.PT_ADMIN_FOLDER_ID:
bObjectIsAccessible = session.GetAdminCatalog()
.IsAdminFolderAccessible(objectID,
accessLevel);

break;

default:
bObjectIsAccessible = session.GetObjectManagers(classID)
.IsObjectAccessible(objectID,
session.GetSessionInfo().GetCurrentUserID(),
accessLevel);

break;

}
return bObjectIsAccessible;

}


Deploy this new PEI and all your problems are gone.
here is a link to the full file.

Monday, May 07, 2007

adding a new file type with a new image associated with it

Most people want to add new file types into the system. Say you want to add avi's or mp3's. You can just upload them, but you get that funky file icon . It would be much cooler if you can change it to something else. There is just a bit involved in doing it, but here are the steps.

First go to the Global Content type map and create a new one. Make sure your new mime type identifier is all the way at the top.

Second go to the file type page. Add a new identifier here for the *.wmv extension. Also move it to the top. Finish out of here.

Next go to the db. In the table ptdocumenttypes there is a field called imageuuid. Take a look at that field for the content type you created before. Make sure it is a different number than the one for the Non Indexed Files Content type (objectid 107). If the number is the same, then go ahead and pick a few numbers in your imageuuid and change them. Be sure to copy the new string, because you will need it later. Also note the objectid of your content type.

Next open the table ptdoctypeinfo. If there is not an entry for your content type enter it now. Otherwise update it. You only need the objectid and the imageuuid. They map to docuemnttypeid and cardimageuuid respectively.

Now upload a wmv file to the kd. This should come up with the missing image icon. That is a good sign. Go to ptimages/.../plumtree/portal/public/img/ and create your icon with the correct name. It is that string you copied before. There are pleanty examples in the location.
one thing to note is that you will have to reupload all the existing files or change them another way.

Wednesday, March 07, 2007

Returned from Europe, and I am ready to focus on ALUI

All,
I know this is off topic, but I have to say Europe is great. However, home is even better. If I never see a smart car again I will be that much happier. I think my next post is going to be about publisher and a caching strategy that helps speed it up. It has to do with settings. Look for this posting some time next week. I will have some time while I sit in a SC hotel wondering what is on all my dishnetwork channels back home.

Thursday, November 09, 2006

Publisher Edit button

People have always asked me how to get the edit button below inside of a content item.

It is pretty simple just use the code below in your presentation template.

pt:nameSpace pt:token="$$PLUM$$" xmlns:pt="http://www.plumtree.com/xmlschemas/ptui/"/>
script>
function edit_article$$PLUM$$() {
var width = 700;
var height = 527;
var left;
var top;
left = window.screenLeft + 10;
top = window.screenTop - 30;
if ( (left + width/2) > screen.availWidth
(top + width/2) > screen.availHeight ) {
left = 0;
top = 0;
}
var params = "height=" + height + ",width=" + width + ",left=" + left + ",top=" + top + ",screenX=" + left + ",screenY=" + top + "toolbar=0,location=0,directories=0,status=1,menubar=0,scrollbars=1,resizable=1";
window.open("/published_tools/content_item.jsp?ciid=&title=ContentItemEditArticleTitle", '', params);
}
/script>
pt:choose xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
pt:when pt:test="stringToACLGroup('group=247;').isMember($currentuser)" xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
input type="button" class="formEditorBtnText" onClick="edit_article$$PLUM$$(); return false" value=" Edit ">
/pt:when>
pt:otherwise xmlns:pt='http://www.plumtree.com/xmlschemas/ptui/'>
/pt:otherwise>
/pt:choose>


It uses soem javascript and a pt tag called choose. In the example above any member of the group 247 has permissions to see the edit button. No one else will see it. NOTE I removed all the '<' so this post will show up

Thursday, October 19, 2006

Oracle SSO and BEA Aqualogic (Plumtree)

Sorry about the delay folks, I was off the last week planning my December wedding. Below you will find exactly how to integrate Oracle SSO into the portal. Some of you may ask what the big deal is, but if you ever dealt with Oracle's SSO, then you will know that it is unlike anything else. I can't wait for them to start using Oblix. First let me describe how this sso works. There are two ways to put something under sso in Oracle. The first is easy, and done through a proxy. There is a mod_osso module installed on the sso box. If you add the proxy for your application, you can then pull the user information out of the header. Check this link out: Oracle sso. Now that is a horrible way to do it. You are always bound to the sso box as a proxy.

Here is the second way: the request hits your app, your app tries to lookup the user information using Oracles SSOSDK. If the user information is not found, your app should then redirect the user to a special url given by the SSOSDK. This is the oracle login page, where the user enters their info. Then they user is rediricted to your app again, where you look up the user info. If the user info is found you log them in. This is absolutely horrible for sso, but after a few weeks I finally figured it out. So please see what I did below. This works for 5-6x

Updated Code:

SSOLoginPage. You have to change the code in this page to alter the call to the sso vendor specific page. Locate the line: SSOLoginInfo info = SSOIntegrator.GetLoginInfo(request); You must change it to: SSOLoginInfo info = SSOIntegrator.GetLoginInfo(request, response); This sends the response object so that you can redirect the user from the sso vendor specific code.

ISSOIntegration. override GetLoginInfo function by adding the IXPResponse parameter.

New code:

OracleSSOVendor. This is the new code that you must write for integration with any SSO vendor. You are going to need to add the following to the GetLoginInfo function. This is after you add the response object to the declaration of course.

OraclePlumtreeSSOEnabler wSSO = new
OraclePlumtreeSSOEnabler(getListenerToken(request), m_pappCookieName, "SSO");

lUserName = wSSO.getUserInfo(request);

if (lUserName == null){
lUserName = wSSo.getSSOUserInfo(request);
if (lUserName == null){
//user has not logged in
response.sendRedirect(wSSO.getSSORedirect(p_requestUrl, p_request));
}
else{
//user has a session, but not in a cookie. add it to a cookie
wSSO.setPartnerAppCookie(p_request, p_response);
}
}


return lUserName;

Now the above only gets you half way. You still need the OraclePlumtreeSSOEnable class. If anyone wants it let me know (andrew.morris@bdg-online.com) I will be glad to send it to you. It is just very confusing to put on a blog. Once you put this in, you are up and running with oracle SSO in no time. I did leave out some information in the set up and all, but I am assuming the user can get a straight forward sso config to work, but just having trouble with oracle. Let me know what you would like me to talk about next. I have done just about everything under the sun, and thinking of where to start is hard. See you next week.

Andrew Morris

Wednesday, October 04, 2006

Who I am and what is this blog about

I have been working with Plumtree, err Aqua Logic User Inter-something, since 2001. I started off in the support department with Plumtree, and worked my way up in the industry. If you worked with Plumtree in the ’01-’03 range, you probably spoke to me on the phone or via email. So if you don’t remember me, that is ok. I have a very bland name that is easy to forget. I mean how bad is Andrew Morris (andrew.morris@bdg-online.com)… Currently I am running the west coast operations for bdg. My job entails gaining clients and getting gigs for my team in the West. I got the idea for this blog from a couple of things; 1) Chris Bucchere, would not stop bugging me about writing my own blog (if you know Chris, you know how he can be.), 2) there are really no blogs out there which have what I feel a Plumtree blog should have.

First I am totally open to questions or suggestions so feel free to post them. Unlike Chris’s blog, look at the links section; I am not going to chat specifically about bdg or Plumtree. I will try and keep my focus on Plumtree, but I may talk about Oracle Portal, or many other things. I think of myself as a .Net guy, but I have been doing Java for the last 2 years. And ohhh does it kill me. You will probably see some rants on this, or even on Plumtree. I want to blog about what everyone who ever used, developed, or sold Plumtree thought, but never had the guts to write it down.

Now don’t get me wrong. Plumtree is a great product. In fact the best I have ever worked with, but that does not mean it has its flaws. However, the one thing Plumtree has is the ability to allow people such as myself to fix these flaws. I mean, come on. How many of you have deployed customizations to just fix bugs? Over the course of my blog entries I will go over talk about what I do for a living. That is designing, implementing things for Plumtree. I could talk about the code I am writing or Plumtree bugs or any number of other applications. So let me know what you think about this, or any suggestions you may have. Stay tuned for the next post, as I will probably rant about the whole SSO Login procedures with Plumtree and Oracle. The rant will include why the Oracle SSO was used, and finally how to do it.