Skip to Content
author's profile photo Former Member
Former Member

Dynamic Group Switch / Group- Role assignment

Hi all,

We built a huge intranet portal with hundreds of roles and groups. The intranet is structured into different MO's (Marktorganisations) which have an initial role and then MO specific roles which are merged.

We recognized that our intranet is getting slower and slower so we are trying cut down the groups and roles a user has assigned. A user should than be only in the groups of the current MO he is visiting, and of course only have the roles assigned to this groups. Every time a user switch to an MO this group switch happens.

The MO-Switcher works like this:

1. Check if a switch has been initialized. If so, get the ID of the new group passed as an URL parameter

2. Remove user from the old group

3. Insert user into the new group

4. Get the navigation target for the "Inside" role within the new MO

5. Redirect to this navigation target

Unfortunately we are facing a delay between the switching of the UME groups and the time the navigation knows about the new roles assignments.

The problem occurs at step 4, after the user has been assigned to the new visitor group. Although the user now has assigned the new roles, sometimes it is not possible to find the navigation node for "Inside".

The curious thing is, sometimes it works, sometimes it doesn't. It looks like the more sub sites a MO has, the less often it works. Especially for HAG we have this problem. For the smaller Mos the switch seems to work.

Details of Step 4:

1. find navigation node within the TLN

2. find the main MO navigation node

3. find the navigation node for "Inside" below the MO main role

I have created an abstract portal component which does the group switch and prints out the results of every single step in finding "Inside".

If it was not possible to find the navigation node, the method waits for 3 seconds and tries it again.

In the first run the methods for retrieving the merged nodes are returning a different result than in the second one.

Since exactly the same code is executed, time can be the only difference. Therefore it should be either a caching "problem" within the methods of the navigation

or the merging of the roles has not been completed by the time the code is execute the first time (maybe due to the group to group to role assignment)

Add a comment
10|10000 characters needed characters exceeded

Related questions

1 Answer

  • author's profile photo Former Member
    Former Member
    Posted on Dec 04, 2007 at 11:28 AM

    Here the code, some might miss them 😊

    1)USER->GROUP change:

    IUserMaint ium = UMFactory.getUserFactory().getMutableUser(user.getUniqueID());
    ium.addtoGroup(newGroup)
    ium.removeFromGroup(oldGroup)
    ium.commit();

    2)invalidate http-Session

    request.getComponentSession().getHttpSession().invalidate();

    3)delete cookies, client-side redirect

    response.write("document.cookies=null;");
    response.write("location.replace("" + newUrl + "");n");
    

    Group switch:

    *************

    private boolean doGroupSwitch(IGroup newGroup) throws UMException {
    
    	IGroupFactory groupFact = UMFactory.getGroupFactory();
    	IUserMaint ium =
    		UMFactory.getUserFactory().getMutableUser(
    			this.request.getUser().getUniqueID());
    
    	String userId = ium.getUniqueID();
    	String newGroupId = newGroup.getUniqueID();
    	boolean changed = false;
    	boolean done = false;
    
    	Iterator it = ROLEMAP.keySet().iterator();
    	// iterate throu all visitor groups
    	while (it.hasNext()) {
    		IGroup group =
    			groupFact.getMutableGroup(((IGroup) it.next()).getUniqueID());
    
    		// remove from old group
    		if (!newGroupId.equals(group.getUniqueID())
    			&& group.isMember(userId, false)) {
    			ium.removeFromGroup(group.getUniqueID());
    			changed = true;
    //				changed = group.removeMember(username);	
    
    		// insert into new group
    		} else if (
    			newGroupId.equals(group.getUniqueID())
    				&& !group.isMember(userId, false)) {
    			ium.addToGroup(group.getUniqueID());
    			changed = true;
    //				changed = group.addMember(username);
    		}
    
    		// if any changes are done, execute commit
    		if (changed) {
    //				group.commit();
    			ium.commit();
    			groupFact.invalidateCacheEntry(group.getUniqueID());
    			done = true;
    		}
    	}
    	return done;
    }
    

    MO switch:

    **********

    public boolean doMOSwitch()
    	throws
    		UMException,
    		InterruptedException,
    		NoSuchRoleException,
    		NamingException {
    
    	// check if MO switch is initialized
    	String newGroupId = this.request.getParameter("newGroupId");
    	if (newGroupId != null) {
    		IGroupFactory groupFact = UMFactory.getGroupFactory();
    		IGroup newGroup = groupFact.getGroup(newGroupId);
    
    		// check if a different MO is selected than the current one
    		// do switch only if a new MO is selected
    		if (newGroup != null
    			&& !this.getCurrentMOName().equals(getMOName(newGroup))) {
    
    			// switch the groups and if done, finde "Inside" and force redirect
    			if (this.doGroupSwitch(newGroup)) {
    
    				this.request.getUser().refresh();
    				this.getHelperService().invalidateNavSession(this.request);
    				
    				// get main MO role
    				IRole newRole = (IRole) ROLEMAP.get(newGroup);
    				INavigationNode entryNode = null;
    
    				int i = 0;
    				// try to find "Inside" if not found wait 3 seconds and try again up to 3 times
    				while (entryNode == null && i < 3) {
    					try {
    						// find "Inside" node
    						entryNode = this.getMOEntryNode(getMOName(newRole));
    
    					} catch (Exception e) {
    						this.response.write("<hr>");
    						Thread.sleep(3000);
    					}
    					i++;
    				}
    				// if found, redirect to "Inside"
    				if (entryNode != null && i == 1) {
    
    					this.response.write("script>n");
    					this.response.write(
    						"window.top.location.replace("/irj/portal?NavigationTarget="
    							+ entryNode.getHashedName()
    							+ "&ORG=SWITCH");n");
    					this.response.write("</script>n");
    
    					return true;
    
    				} else {
    					throw new NoSuchRoleException(
    						"No entry role found for: "
    							+ this.getMORoleName(getMOName(newRole)));
    				}
    			}
    		}
    	}
    	return false;
    }
    

    Find "Inside"

    **************

    public INavigationNode getMOEntryNode(String mo)
    	throws NamingException, NoSuchRoleException {
    
    	INavigationNode entryNode = null;
    
    	if (mo != null && mo.length() > 0) {
    		String moRole = this.getMORoleName(mo);
    
    		NavigationNodes childs = null;
    
    		// find navigation node from TLN
    		INavigationNode hgi = this.getHGINode();
    
    		if (hgi != null) {
    
    			this.response.write(hgi.getName() + "<br><br>"); see attachment line 1
    
    			childs = hgi.getChildren(this.getEnvironment());
    			if (childs != null) {
    
    				INavigationNode child = null;
    				Iterator it = childs.iterator();
    
    				// Iterate throu all childs and find main MO role (should always be the fist one)
    				while (it.hasNext() && entryNode == null) {
    					child = (INavigationNode) it.next();
    
    					this.response.write(child.getName() + "<br><br>"); see attachment line 2
    
    					// if main MO navigaion node found, get "Inside"
    					if (child.contains(moRole)) {
    						entryNode = this.findInsideChildNode(child);
    						if (entryNode == null) {
    							throw new NamingException("NavigationNode: Inside not found!");
    						}
    					}
    				}
    				if (entryNode == null) {
    					throw new NoSuchRoleException(
    						"MO role not found: " + moRole);
    				}
    			} else {
    				throw new NamingException(
    					"No children found for: " + hgi.getName());
    			}
    		} else {
    			throw new NoSuchRoleException("role not found!");
    		}
    	} else {
    		throw new NoSuchRoleException("Parameter mo not defined!");
    	}
    
    	this.response.write(entryNode.getName() + "<br><br>"); see attachment line 3
    
    	return entryNode;
    }
    

    Get HGI Node:

    *****************

    private INavigationNode getHGINode() throws NamingException {
    	INavigationNode hgi = null;
    	NavigationNodes topLvel =
    		this.getService().getInitialNodes(this.getEnvironment());
    	Iterator it = topLvel.iterator();
    	while (it.hasNext()) {
    		hgi = (INavigationNode) it.next();
    		if (hgi
    			.contains("ROLES://portal_content/com.comp/webContent/com.comp.intra.glo.c.main_role/global_intranet")) {
    			return hgi;
    		}
    	}
    	return null;
    }
    

    Finde "Inside"

    ****************

    private INavigationNode findInsideChildNode(INavigationNode node)
    	throws NamingException {
    	if (node != null) {
    		NavigationNodes childs = node.getChildren(this.getEnvironment());
    		if (childs != null) {
    			Iterator it = childs.iterator();
    			INavigationNode child = null;
    			String name = null;
    			while (it.hasNext()) {
    				child = (INavigationNode) it.next();
    				name = this.getHighesPriorityRoleName(child);
    				name = name.substring(name.lastIndexOf("/") + 1);
    				if (name.toLowerCase().startsWith("inside")) {
    					return child;
    				}
    			}
    		}
    	}
    	return null;
    }

    Any ideas why we have a delay and it sometimes work and sometimes not?

    Add a comment
    10|10000 characters needed characters exceeded

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.