Thanks guys, I'll try out your suggestions, and I think I have plenty of information to get done what I want.
 
Seth


From: Christofer Dutz [mailto:[EMAIL PROTECTED]
Sent: Friday, June 02, 2006 3:30 AM
To: users@cocoon.apache.org
Subject: AW: Restrict users to flow

Hmmm … don’t know why my last post didn’t make it into the List … well … here another try ;)

 

Hi Foss,

 

Just read your question ..

How about making all Pipelines you want to protect internal pipelines?

If the user enters the urls manually they will get “page not found”s but if Flowscript uses a sendPage it will be shown.

I use this technique to protect my pipelines from power-user manipulation.

 

Regargs,

    Christofer Dutz

 

[ c h r i s t o f e r   d u t z ]

 

IT-Berater

univativ GmbH & Co. KG

Robert-Bosch-Str. 7, 64293 Darmstadt

 

fon: 0 61 51 / 66 717 - 21

fax: 0 61 51 / 66 717 - 29

email: [EMAIL PROTECTED]

http://www.univativ.de

 

Darmstadt, Stuttgart, Karlsruhe, Düsseldorf


From: tedwards [mailto:[EMAIL PROTECTED]
Sent: Thursday, June 01, 2006 8:18 PM
To: users@cocoon.apache.org
Subject: Re: Restrict users to flow

Hi Seth,
I actually access the navigation.xml from within flow.
I pass all function calls through a 'main' function and this calls a 'checkUserSecurity(functionName)' function where the user's access is checked.

In the sitemap I have:
            <map:match pattern="*.do">
                <map:call function="main">
                    <map:parameter name="page" value="{1}" />                    
                </map:call>
            </map:match>

In my navigation.xml I have:
        <menu label="Access" href="">
            <menu-item href="" ignoreRole="true" label="Login" roleName="Public" role="0"/>
            <menu-item href="" ignoreRole="true" label="Logout" roleName="Public" role="0"/>
            <menu-item href="" label="Edit password reminder lists" roleName="Administer Users" role="1"/>       
            <menu-item href="" label="eService Admin" roleName="Administer Eservices" role="512"/>       
            <menu-item href="" label="Database Connections" roleName="Administer Hierarchies" role="256"/>
            <menu-item href="" label="View Link Types" roleName="Public" role="1"/>
            <menu-item href="" label="Edit Sitemap Components" roleName="Administer Hierarchies" role="1024"/>
        </menu>

If I am trying to call 'signOnForm.do', it gets passed to 'main'. My credentials and the role against the function are checked against each other and if its OK the finction is then called.
If the function has an 'ignoreRole' attribute set to true, then no checking takes place and the function is called.
I use a simple bit flag mechanism to determine a user's permissions. The user's role number (stored in user.userLogin.rol_num ) is ANDed against the function's role number. Eg if a user's role number is 2560 and the function has a role of 512 then the user has access to this function (2560 AND 512 = 512 [true]).
The user details can be obtained from a database or a simple ACL xml file living under cocoon. The advantage for me is that I can impose a fairly flexible authentication structure without having to resort to any java (such is the wonderful nature of Cocoon!!).

The relevant bits of flow are listed below. Using this process I can change menu items on the fly depending on user permissions by transforming the navigation.xml document and bitshifting the function's role and the user's role in XSL. But that's another story!

I hope this lengthy reply helps!

Regards,
Tony

function main() {
  
    var funName = cocoon.parameters["page"];
    print("Function Main(). Calling " + funName + "..."); 
    var fun = this[funName];
       
    print("Check that user has security to access the function: '" + funName + "'");
    print("First: make sure user's security setting is in session:");
    var userRoleNum = 0;
    userRoleNum = cocoon.session.getAttribute("securityAccess");
       
    if(((userRoleNum == null) || (userRoleNum == 0)) && (user != null)){
        print("Users session role num = " + userRoleNum);   
        print("User's session role num has been clobbered. Re-add it.");
        cocoon.session.setAttribute("securityAccess",user.userLogin.rol_num);
    }
    var functionRedirect = checkUserSecurity(funName);
    print("Redirected function = " + functionRedirect);
    fun = this[functionRedirect];
   
    var args = new Array(arguments.length -1);
   
    for (var i = 1; i < arguments.length; i++) {
        args[i-1] = arguments[i];
        print("Args: " + args[i-1]);
    }
     
    message="";   
    fun.apply(args);
   
}

function checkUserSecurity(psFuncName){
    //Check user role against function role and returns the
    // function you're trying to get to if OK or else directs you to 
    // the welcome screen where you can read the error message.
    print("*****************************************************************");
    print("In checkUserSecurity. Checking user access to '" + psFuncName + "'");
    print("Is the function an aim specific function?");

    print("Do we ignore this role?");
    var ignoreRole = getIgnoreRoleStatus(psFuncName);
    if(ignoreRole == "true"){
        print("Yes we do.");
        return psFuncName;
    }
     
    if((user == null) || (typeof(user) == 'undefined')){
        print("user is null - hasn't logged on.");
        return 'welcome';
    }
    var userRole = user.userLogin.rol_num;
    print("User's magic number = " + userRole);
 
     
    var lFuncMagNum = getFunctionMagicNumber(psFuncName);
    print("Role number for this function = " + lFuncMagNum);
     
    var biLevel = new Packages.java.math.BigInteger(userRole + "");
    var biAccess = new Packages.java.math.BigInteger(lFuncMagNum + "");         
    var result = biLevel.and(biAccess).intValue();         
    print("Result of ANDing " + userRole + " AND " + lFuncMagNum + " = " + result);
    if(result > 0){
        print("*****************************************************************");
        return psFuncName;
    } else {
        message = "You don't have the required pemissions to access the '" + psFuncName + "' function.";
        setMessage(message);
            print("*****************************************************************");
        return 'welcome';
    }     
}


function getFunctionMagicNumber(psFunctionName){
    print("Loading the navigation document.");
    var navDoc = loadDocument("cocoon:/xml/navigation.xml");
    if(navDoc != null){
        print("Looking for element with href attribute of '" + psFunctionName + ".do'");         
        var navElement = getNodesByAttribute(navDoc, "menu-item", "href", Trim(psFunctionName) + ".do");
        if(navElement != null){
            print("Found element, get role attribute.");
            var roleVal = getNodeAttributeValue(navElement, "role");
            var label =  getNodeAttributeValue(navElement, "label");
            print("Menu item label = " + label);             
            print("Role setting = " + roleVal);
            return roleVal;
 
        } else {
            print("Could not find role attribute in element " + getNodeText(navElement));
            return null;
        }
    } else {
        message = "Could not find navigation document. Please notify administrator.";
        print(message);
        return null;
    }
}
function getNodesByAttribute(document, elmntName, attrName, attrValue) {
    /** elmntName = "hNode"
     * attrName = the attribute we're trying to find. 
     * attrValue = the atrribute's value we're trying to retrieve
     * Returns the nodes whose attr = the value parm */
    print("In getNodesByAttribute: element Name =  " + elmntName + "; Attribute Name = " + attrName + "; Attribute Value = " + attrValue);
    if(document == null){
        print("Document is null!");
        return null;
    }
    var node = null;
     
    print("Getting all parentNode or childNode elements: getElementsByTagName(" + elmntName + ")");
    var pnodes = document.getElementsByTagName(elmntName);
 
    var nodeLen = pnodes.getLength();
    print("Number of elements retrieved = " + nodeLen);
    if (nodeLen == 0) {
        //Node don't exist!
        return null;
    } else {
        //We've found some Node elements, 
        //see if the id attribute value = nodeId parm.
        for (var i = 0; i < nodeLen; i++) {
            node = pnodes.item(i);
            if (node != null) {
                if (node.hasAttributes()) {
                    var attributes = node.getAttributes();
                    var idAttribute = attributes.getNamedItem(attrName);
                    if (idAttribute != null){
                        if (idAttribute.getNodeValue().equals(attrValue)) {
                            return node;
                        }
                    } else {
                        return null;
                    }
                }
            }
        }
        return null;
    }
}

function getNodeAttributeValue(domNode,attributeName){
    if(domNode == null){
        return null;
    }
    if (domNode.hasAttributes()) {
        var attributes = domNode.getAttributes();
        var idAttribute = attributes.getNamedItem(attributeName);
        if (idAttribute != null){
            return idAttribute.getNodeValue();
        } else {
            return null;
        }
    } else {
        return null;
    }
 

 


Von: Seth Foss [mailto:[EMAIL PROTECTED]
Gesendet: Mittwoch, 31. Mai 2006 14:28
An: users@cocoon.apache.org
Betreff: RE: Restrict users to flow

 

Tony,

    That looks like just what I need. Could you give me an example of how your are accessing that xml from your sitemap?

 

Seth

 


From: tedwards [mailto:[EMAIL PROTECTED]
Sent: Tuesday, May 30, 2006 7:06 PM
To: users@cocoon.apache.org
Subject: Re: Restrict users to flow

Hi Seth,
I restrict what users can and can't do by running them through a 'traffic cop' of sorts.
I have a navigation document which performs 2 functions: 1 is to generate the menus that the program displays and the other is to determine who can have access to a particular portion of the application.

For example:

A section of my navigation.xml looks like this:
    <menu_category type="non-visible">
        <menu label="non-visible">
            <menu-item href="" label="processLinks" roleName="Public" role="1"/>
            <menu-item href="" label="noticeEdit" roleName="Public" role="1"/>
            <menu-item href="" label="searchHrcy" roleName="Admin" role="256"/>
            <menu-item href="" label="getChildNodesOnly" roleName="Public" role="1"/>
       </menu>
    </menu_category>

When a user tries to access a particular flow function like 'searchHrcy.do', their user permissions (a global variable obtained at login) is compared to the role attribute of the menu-item. If they don't have sufficient privileges to access this function then they are redirected.
Similarly if they attempt to access and function not listed in the navigation.xml, an error is generated and they are redirected.
All this role checking and redirection is handled by flow. This could be extended to include any pipeline calls as well by listing them in the navigation document and using flow to call sendPage(menu-item).

I hope this makes sense. The application I am writing required really fine grained access level so I knocked up this 'traffic cop' to check every public flow function.
If you need more detail, let me know.

Regards
Tony


Seth Foss wrote:

How do I restrict a user from accessing pipelines outside of flowscript?  I can figure out how to redirect un-authenticated users to a login page, but if logged-in users manually enter a pipeline into the address bar, how do I redirect them into my flowscript. I plan on using continuations, so Submits and Nexts will not direct to the correct pages without the flowscript running.

 

Seth Foss

--

This email is from Civica Pty Limited and it, together with any attachments, is confidential to the intended recipient(s) and the contents may be legally privileged or contain proprietary and private information. It is intended solely for the person to whom it is addressed. If you are not an intended recipient, you may not review, copy or distribute this email. If received in error, please notify the sender and delete the message from your system immediately. Any views or opinions expressed in this email and any files transmitted with it are those of the author only and may not necessarily reflect the views of Civica and do not create any legally binding rights or obligations whatsoever. Unless otherwise pre-agreed by exchange of hard copy documents signed by duly authorised representatives, contracts may not be concluded on behalf of Civica by email. Please note that neither Civica nor the sender accepts any responsibility for any viruses and it is your responsibility to scan the email and the attachments (if any). All email received and sent by Civica may be monitored to protect the business interests of Civica.

Reply via email to