Project

General

Profile

« Previous | Next » 

Revision 7667

Added by Jing Tao over 11 years ago

Add a test for testing access control for the solr query.

View differences:

test/edu/ucsb/nceas/metacat/dataone/SolrQueryAccessFilterTest.java
1
package edu.ucsb.nceas.metacat.dataone;
2

  
3
import java.io.ByteArrayInputStream;
4
import java.io.File;
5
import java.io.FileInputStream;
6
import java.io.InputStream;
7
import java.util.ArrayList;
8
import java.util.List;
9

  
10
import javax.xml.parsers.DocumentBuilder;
11
import javax.xml.parsers.DocumentBuilderFactory;
12
import javax.xml.xpath.XPath;
13
import javax.xml.xpath.XPathConstants;
14
import javax.xml.xpath.XPathExpression;
15
import javax.xml.xpath.XPathFactory;
16

  
17
import junit.framework.Test;
18
import junit.framework.TestSuite;
19

  
20
import org.dataone.client.ObjectFormatCache;
21
import org.dataone.configuration.Settings;
22
import org.dataone.service.types.v1.AccessPolicy;
23
import org.dataone.service.types.v1.AccessRule;
24
import org.dataone.service.types.v1.Identifier;
25
import org.dataone.service.types.v1.Permission;
26
import org.dataone.service.types.v1.Person;
27
import org.dataone.service.types.v1.Session;
28
import org.dataone.service.types.v1.Subject;
29
import org.dataone.service.types.v1.SubjectInfo;
30
import org.dataone.service.types.v1.SystemMetadata;
31
import org.dataone.service.util.Constants;
32
import org.junit.Before;
33
import org.w3c.dom.Document;
34
import org.w3c.dom.Node;
35
import org.w3c.dom.NodeList;
36
import org.xml.sax.InputSource;
37

  
38

  
39
/**
40
 * A test class to test the access filter mechanism for the solr query
41
 * @author tao
42
 *
43
 */
44
public class SolrQueryAccessFilterTest extends D1NodeServiceTest {
45
    
46
    private static final String SOLR = "solr";
47
    private static final String EML201NAMESPACE = "eml://ecoinformatics.org/eml-2.0.1";
48
    private static final String CREATEUSER = "CN=Christopher Jones A583,O=Google,C=US,DC=cilogon,DC=org";
49
    private static final String QUERYUSER = "CN=ben leinfelder A756,O=Google,C=US,DC=cilogon,DC=org";
50
    private static final String GROUP1 = "CN=PISCO-data-managers,DC=cilogon,DC=org";
51
    private static final String GROUP2 = "CN=dataone-coredev,DC=cilogon,DC=org";
52
    private static final String EMLFILE = "test/restfiles/knb-lter-gce.109.6.xml";
53
    private static final String IDXPATH = "//response/result/doc/str[@name='id']/text()";
54
    
55
    /**
56
     * Build the test suite
57
     * @return
58
     */
59
    public static Test suite() {
60
      
61
      TestSuite suite = new TestSuite();
62
      suite.addTest(new SolrQueryAccessFilterTest("testPublicReadable"));
63
  
64
      
65
      return suite;
66
      
67
    }
68
    
69
    /**
70
     * Set up the test fixtures
71
     * 
72
     * @throws Exception
73
     */
74
    @Before
75
    public void setUp() throws Exception {
76
      super.setUp();
77
      // set up the configuration for d1client
78
      Settings.getConfiguration().setProperty("D1Client.cnClassName", MockCNode.class.getName());
79
    }
80
    
81
    /**
82
     * Constructor for the tests
83
     * 
84
     * @param name - the name of the test
85
     */
86
    public SolrQueryAccessFilterTest(String name) {
87
      super(name);
88
      
89
    }
90
    
91
   
92
    
93
    /**
94
     * Test to query a public readable document
95
     */
96
    public void testPublicReadable() throws Exception {
97
        Session session = getSession(CREATEUSER, null);
98
        Identifier id = generateIdentifier();
99
        String[] allowUsers = {Constants.SUBJECT_PUBLIC};
100
        File object = new File(EMLFILE);
101
        SystemMetadata sysmeta = generateSystemMetadata(id, session.getSubject(), object , allowUsers);
102
        createObject(session, id, object, sysmeta);
103
        Session querySession = getSession(Constants.SUBJECT_PUBLIC, null);
104
        Thread.sleep(10000);
105
        String resultId = query(querySession, id);
106
        assertTrue("In the testPublicReadable method, the query result should have the id "+id.getValue(), resultId.equals(id.getValue()));
107
        session = getSession(CREATEUSER, null);
108
        delete(session, id);
109
    }
110
    
111
    
112
    /**
113
     * Test to query a document which can only be read by a specified user
114
     */
115
    public void testOnlyUserReadable() {
116
        
117
    }
118
    
119
    /**
120
     * Test to query a document which can be read by a specified group
121
     */
122
    public void testGroupReadable() {
123
        
124
    }
125
    
126
    
127
    /**
128
     * Test to query a document which only can be read by the rightHolder
129
     */
130
    public void testOnlyRightHolderReadable() {
131
        
132
    }
133
    
134
    /*
135
     * constructs a "fake" session with the specified subject and groups.
136
     * If groups is not null, the session will have a subjectinfo which contains the person with the subject and is the member of the groups.
137
     * @return
138
     */
139
    private Session getSession(String subjectValue, String[]groups) throws Exception {
140
        Session session = new Session();
141
        Subject subject = new Subject();
142
        subject.setValue(subjectValue);
143
        session.setSubject(subject);
144
        if(groups != null) {
145
            Person person = new Person();
146
            person.setSubject(subject);
147
            person.setVerified(new Boolean(true));
148
            List<Subject>groupSubjects = new ArrayList<Subject>();
149
            for(String group: groups) {
150
                Subject groupSub = new Subject();
151
                groupSub.setValue(group);
152
                groupSubjects.add(groupSub);
153
            }
154
            person.setIsMemberOfList(groupSubjects);
155
            SubjectInfo subjectInfo = new SubjectInfo();
156
            subjectInfo.addPerson(person);
157
            session.setSubjectInfo(subjectInfo);
158
        }
159
        return session;
160
    }
161
    
162
    /*
163
     * Create a data object in the dataone server. 
164
     * Return the identifier of the created object
165
     */
166
    private void createObject(Session session, Identifier id, File object, SystemMetadata sysmeta) throws Exception {
167
        MNodeService.getInstance(request).create(session, id, new FileInputStream(object), sysmeta);
168
        
169
    }
170
    
171
    private Identifier generateIdentifier() {
172
        Identifier guid = new Identifier();
173
        long random = Math.round(Math.random()*10000);
174
        guid.setValue("test." + System.currentTimeMillis()+(new Long(random)).toString());
175
        return guid;
176
    }
177
    
178
    /*
179
     * Delete the given id.
180
     */
181
    private void delete(Session session, Identifier id) throws Exception {
182
        MNodeService.getInstance(request).delete(session, id);
183
    }
184
    
185
    
186
    
187
    /*
188
     * Generate system metadata for the file
189
     */
190
    private SystemMetadata generateSystemMetadata(Identifier id, Subject owner, File objectFile, String[] allowedSubjects) throws Exception{
191
        SystemMetadata sysmeta = createSystemMetadata(id, owner, new FileInputStream(objectFile));
192
        AccessPolicy accessPolicy = null;
193
        if(allowedSubjects != null && allowedSubjects.length >0) {
194
            accessPolicy = new AccessPolicy();
195
            for(int i=0; i<allowedSubjects.length; i++) {
196
                AccessRule allow = new AccessRule();
197
                allow.addPermission(Permission.READ);
198
                Subject subject =  new Subject();
199
                subject.setValue(allowedSubjects[i]);
200
                allow.addSubject(subject);
201
                accessPolicy.addAllow(allow);
202
            }
203
        }
204
        sysmeta.setAccessPolicy(accessPolicy);
205
        sysmeta.setFormatId(ObjectFormatCache.getInstance().getFormat(EML201NAMESPACE).getFormatId());
206
        return sysmeta;
207
    }
208
    
209
    /*
210
     * Query the server to find the doc which matches the specified id
211
     */
212
    private String query(Session session, Identifier id) throws Exception{
213
        String query = generateQuery(id.getValue());
214
        InputStream input = MNodeService.getInstance(request).query(SOLR, query);
215
        return extractId(input);
216
    }
217
    
218
    /*
219
     * Extract the return id from the query result input stream
220
     */
221
    private String extractId(InputStream input ) throws Exception {
222
        String id = null;
223
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
224
        DocumentBuilder builder = factory.newDocumentBuilder();
225
        Document doc = builder.parse(new InputSource(input));
226
       
227
        XPathFactory xPathfactory = XPathFactory.newInstance();
228
        XPath xpath = xPathfactory.newXPath();
229
        XPathExpression expr = xpath.compile(IDXPATH);
230
        Object result = expr.evaluate(doc, XPathConstants.NODESET);
231
        System.out.println("================ result is "+result);
232
        if(result != null) {
233
            NodeList nodes = (NodeList) result;
234
            if(nodes != null) {
235
                System.out.println("the length of nodes is "+nodes.getLength());
236
                Node node = nodes.item(0);
237
                if(node != null) {
238
                    id = node.getNodeValue();
239
                }
240
                
241
            }
242
            
243
        }
244
       
245
        System.out.println("the id is ====== "+id);
246
        return id;
247

  
248
    
249
    }
250
    /*
251
     * Make a query string which will query "id= the specified id".
252
     * @param id
253
     * @return
254
     */
255
    private String generateQuery(String id) {
256
        String query = "q=id:"+id+"&fl=id,title";
257
        return query;
258
    }
259
}

Also available in: Unified diff