Ignore:
Timestamp:
2012-02-15T15:14:09+13:00 (12 years ago)
Author:
sjm84
Message:

Adding in security capabilities for Greenstone 3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/Collection.java

    r24583 r25092  
    3030
    3131import java.io.*;
    32 import java.io.File;
    33 import java.util.HashMap;
    3432import java.util.*;
    3533
     
    7068    /** earliestDatestamp of this collection. Necessary for OAI */
    7169    protected long earliestDatestamp = 0;
     70
     71    /** Stores the default accessibility of guest users */
     72    protected boolean _publicAccess = true;
     73    /** Stores the scope of any security rules (either collection or document) */
     74    protected boolean _securityScopeCollection = true;
     75
     76    protected HashMap<String, ArrayList<Element>> _documentSets = new HashMap<String, ArrayList<Element>>();
     77
     78    protected ArrayList<HashMap<String, ArrayList<String>>> _securityExceptions = new ArrayList<HashMap<String, ArrayList<String>>>();
    7279
    7380    /**
     
    125132            col_type = search.getAttribute(GSXML.TYPE_ATT);
    126133        }
    127        
     134
    128135        Element browse = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.INFODB_ELEM);
    129136        if (browse != null)
     
    138145        // process the metadata and display items
    139146        findAndLoadInfo(coll_config_xml, build_config_xml);
     147
     148        loadSecurityInformation(coll_config_xml);
    140149
    141150        // now do the services
     
    207216    protected Element loadBuildConfigFile()
    208217    {
    209 
    210218        File build_config_file = new File(GSFile.collectionBuildConfigFile(this.site_home, this.cluster_name));
    211219        if (!build_config_file.exists())
     
    232240    protected boolean findAndLoadInfo(Element coll_config_xml, Element build_config_xml)
    233241    {
    234 
    235         // metadata
    236242        Element meta_list = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
    237243        addMetadata(meta_list);
     
    293299        return true;
    294300
     301    }
     302
     303    protected void loadSecurityInformation(Element coll_config_xml)
     304    {
     305        Element securityBlock = (Element) GSXML.getChildByTagName(coll_config_xml, GSXML.SECURITY_ELEM);
     306
     307        if(securityBlock == null)
     308        {
     309            return;
     310        }
     311       
     312        String scope = securityBlock.getAttribute(GSXML.SCOPE_ATT);
     313        String defaultAccess = securityBlock.getAttribute(GSXML.DEFAULT_ACCESS_ATT);
     314
     315        if (defaultAccess.toLowerCase().equals("public"))
     316        {
     317            _publicAccess = true;
     318        }
     319        else if (defaultAccess.toLowerCase().equals("private"))
     320        {
     321            _publicAccess = false;
     322        }
     323        else
     324        {
     325            logger.warn("Default access for collection " + this.cluster_name + " is neither public or private, assuming public");
     326        }
     327
     328        if (scope.toLowerCase().equals("collection"))
     329        {
     330            _securityScopeCollection = true;
     331        }
     332        else if (scope.toLowerCase().equals("documents") || scope.toLowerCase().equals("document"))
     333        {
     334            _securityScopeCollection = false;
     335        }
     336        else
     337        {
     338            logger.warn("Security scope is neither collection or document, assuming collection");
     339        }
     340
     341        NodeList exceptions = GSXML.getChildrenByTagName(securityBlock, GSXML.EXCEPTION_ELEM);
     342
     343        if (exceptions.getLength() > 0)
     344        {
     345            if (!_securityScopeCollection)
     346            {
     347                NodeList documentSetElems = GSXML.getChildrenByTagName(securityBlock, GSXML.DOCUMENT_SET_ELEM);
     348                for (int i = 0; i < documentSetElems.getLength(); i++)
     349                {
     350                    Element documentSet = (Element) documentSetElems.item(i);
     351                    String setName = documentSet.getAttribute(GSXML.NAME_ATT);
     352                    NodeList matchStatements = GSXML.getChildrenByTagName(documentSet, GSXML.MATCH_ELEM);
     353                    ArrayList<Element> matchStatementList = new ArrayList<Element>();
     354                    for (int j = 0; j < matchStatements.getLength(); j++)
     355                    {
     356                        matchStatementList.add((Element) matchStatements.item(j));
     357                    }
     358                    _documentSets.put(setName, matchStatementList);
     359                }
     360            }
     361
     362            for (int i = 0; i < exceptions.getLength(); i++)
     363            {
     364                HashMap<String, ArrayList<String>> securityException = new HashMap<String, ArrayList<String>>();
     365                ArrayList<String> exceptionGroups = new ArrayList<String>();
     366                ArrayList<String> exceptionSets = new ArrayList<String>();
     367
     368                Element exception = (Element) exceptions.item(i);
     369                NodeList groups = GSXML.getChildrenByTagName(exception, GSXML.GROUP_ELEM);
     370                for (int j = 0; j < groups.getLength(); j++)
     371                {
     372                    Element group = (Element) groups.item(j);
     373                    String groupName = group.getAttribute(GSXML.NAME_ATT);
     374                    exceptionGroups.add(groupName);
     375                }
     376                NodeList docSets = GSXML.getChildrenByTagName(exception, GSXML.DOCUMENT_SET_ELEM);
     377                for (int j = 0; j < docSets.getLength(); j++)
     378                {
     379                    Element docSet = (Element) docSets.item(j);
     380                    String docSetName = docSet.getAttribute(GSXML.NAME_ATT);
     381                    exceptionSets.add(docSetName);
     382                }
     383
     384                securityException.put("groups", exceptionGroups);
     385                securityException.put("sets", exceptionSets);
     386                _securityExceptions.add(securityException);
     387            }
     388        }
    295389    }
    296390
     
    431525                classifier = request.getAttribute("classifier");
    432526            }
    433            
     527
    434528            // check for version file
    435529            String directory = new File(GSFile.collectionConfigFile(this.site_home, this.cluster_name)).getParent() + File.separator;
     
    661755            }
    662756        }
     757        else if (type.equals(GSXML.REQUEST_TYPE_SECURITY))
     758        {
     759            String oid = request.getAttribute("oid");
     760            ArrayList<String> groups = getPermittedGroups(oid);
     761           
     762            Element groupList = this.doc.createElement(GSXML.GROUP_ELEM + GSXML.LIST_MODIFIER);
     763            response.appendChild(groupList);
     764           
     765            for(String groupName : groups)
     766            {
     767                Element group = this.doc.createElement(GSXML.GROUP_ELEM);
     768                groupList.appendChild(group);
     769                group.setAttribute(GSXML.NAME_ATT, groupName);
     770            }
     771        }
    663772        else
    664773        { // unknown type
     
    669778    }
    670779
     780    protected ArrayList<String> getPermittedGroups(String oid)
     781    {
     782        ArrayList<String> groups = new ArrayList<String>();
     783       
     784        if (_securityScopeCollection)
     785        {
     786            if (_publicAccess)
     787            {
     788                groups.add("");
     789            }
     790            else
     791            {
     792                for (HashMap<String, ArrayList<String>> exception : _securityExceptions)
     793                {
     794                    for (String group : exception.get("groups"))
     795                    {
     796                        groups.add(group);
     797                    }
     798                }
     799            }
     800        }
     801        else
     802        {
     803            if(oid != null && !oid.equals(""))
     804            {
     805                boolean inSet = false;
     806                for (HashMap<String, ArrayList<String>> exception : _securityExceptions)
     807                {
     808                    for (String setName : exception.get("sets"))
     809                    {
     810                        if (documentIsInSet(oid, setName))
     811                        {
     812                            inSet = true;
     813                            for (String group : exception.get("groups"))
     814                            {
     815                                groups.add(group);
     816                            }
     817                        }
     818                    }
     819                }
     820               
     821                if(!inSet && _publicAccess)
     822                {
     823                    groups.add("");
     824                }
     825            }
     826            else
     827            {
     828                groups.add("");
     829            }
     830        }
     831
     832        return groups;
     833    }
     834
     835    protected boolean documentIsInSet(String oid, String setName)
     836    {
     837        ArrayList<Element> matchStatements = _documentSets.get(setName);
     838        if (matchStatements == null || matchStatements.size() == 0)
     839        {
     840            return false;
     841        }
     842
     843        for (Element currentMatchStatement : matchStatements)
     844        {
     845            String fieldName = currentMatchStatement.getAttribute(GSXML.FIELD_ATT);
     846            if (fieldName == null || fieldName.equals(""))
     847            {
     848                fieldName = "oid";
     849            }
     850
     851            String type = currentMatchStatement.getAttribute(GSXML.TYPE_ATT);
     852            if (type == null || type.equals(""))
     853            {
     854                type = "match";
     855            }
     856
     857            String fieldValue = "";
     858            if (!fieldName.equals("oid"))
     859            {
     860                fieldValue = getFieldValue(oid, fieldName);
     861                if(fieldValue == null)
     862                {
     863                    return false;
     864                }
     865            }
     866            else
     867            {
     868                fieldValue = oid;
     869            }
     870
     871            String matchValue = GSXML.getNodeText(currentMatchStatement);
     872            if (type.equals("match"))
     873            {
     874                if(matchValue.equals(fieldValue))
     875                {
     876                    return true;
     877                }
     878            }
     879            else if (type.equals("regex"))
     880            {
     881                if(fieldValue.matches(matchValue))
     882                {
     883                    return true;
     884                }
     885            }
     886            else
     887            {
     888                logger.warn("Unknown type of match specified in security block of collection " + this.cluster_name + ".");
     889            }
     890        }
     891
     892        return false;
     893    }
     894
     895    protected String getFieldValue(String oid, String fieldName)
     896    {
     897        Element metadataMessage = this.doc.createElement(GSXML.MESSAGE_ELEM);
     898        Element metadataRequest = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, this.cluster_name + "/DocumentMetadataRetrieve", new UserContext());
     899        metadataMessage.appendChild(metadataRequest);
     900
     901        Element paramList = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
     902        metadataRequest.appendChild(paramList);
     903       
     904        Element param = this.doc.createElement(GSXML.PARAM_ELEM);
     905        paramList.appendChild(param);
     906       
     907        param.setAttribute(GSXML.NAME_ATT, "metadata");
     908        param.setAttribute(GSXML.VALUE_ATT, fieldName);
     909       
     910        Element docList = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
     911        metadataRequest.appendChild(docList);
     912       
     913        Element doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
     914        docList.appendChild(doc);
     915       
     916        doc.setAttribute(GSXML.NODE_ID_ATT, oid);
     917       
     918        Element response = (Element) this.router.process(metadataMessage);
     919        NodeList metadataElems = response.getElementsByTagName(GSXML.METADATA_ELEM);
     920       
     921        if(metadataElems.getLength() > 0)
     922        {
     923            Element metadata = (Element) metadataElems.item(0);
     924            return GSXML.getNodeText(metadata);
     925        }
     926       
     927        return null;
     928    }
    671929}
Note: See TracChangeset for help on using the changeset viewer.