Project

General

Profile

1
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2014 Regents of the University of California and the
4
 *              National Center for Ecological Analysis and Synthesis
5
 *  Purpose: To test the Access Controls in metacat by JUnit
6
 *
7
 *   '$Author: slaughter $'
8
 *     '$Date: $'
9
 * '$Revision:$'
10
 *
11
 * This program is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
 */
25

    
26
package edu.ucsb.nceas.metacat.admin.upgrade.dataone;
27

    
28
import java.io.ByteArrayInputStream;
29
import java.io.InputStream;
30
import java.util.Hashtable;
31

    
32
import junit.framework.Test;
33
import junit.framework.TestSuite;
34

    
35
import org.dataone.client.CNode;
36
import org.dataone.client.D1Client;
37
import org.dataone.service.exceptions.ServiceFailure;
38
import org.dataone.service.types.v1.AccessPolicy;
39
import org.dataone.service.types.v1.AccessRule;
40
import org.dataone.service.types.v1.Identifier;
41
import org.dataone.service.types.v1.Permission;
42
import org.dataone.service.types.v1.Session;
43
import org.dataone.service.types.v1.Subject;
44
import org.dataone.service.types.v1.SystemMetadata;
45
import org.junit.Before;
46

    
47
import edu.ucsb.nceas.metacat.IdentifierManager;
48
import edu.ucsb.nceas.metacat.client.Metacat;
49
import edu.ucsb.nceas.metacat.client.MetacatFactory;
50
import edu.ucsb.nceas.metacat.client.MetacatInaccessibleException;
51
import edu.ucsb.nceas.metacat.dataone.D1NodeServiceTest;
52
import edu.ucsb.nceas.metacat.dataone.MNodeService;
53
import edu.ucsb.nceas.metacat.dataone.SyncAccessPolicy;
54
import edu.ucsb.nceas.utilities.access.AccessControlInterface;
55

    
56
/**
57
 * A JUnit test for testing syncing access policies between MN -> CN after local
58
 * update by metacat services
59
 */
60
public class SyncAccessPolicyTest extends D1NodeServiceTest {
61

    
62
	private Metacat m;
63

    
64
	/**
65
	 * Constructor to build the test
66
	 * 
67
	 * @param name
68
	 *            the name of the test method
69
	 */
70
	public SyncAccessPolicyTest(String name) {
71
		super(name);
72
	}
73

    
74
	/**
75
	 * Establish a testing framework by initializing appropriate objects
76
	 */
77
	@Before
78
	public void setUp() throws Exception {
79
		// super.setUp();
80

    
81
		try {
82
			debug("Test Metacat: " + metacatUrl);
83
			m = MetacatFactory.createMetacatConnection(metacatUrl);
84
		} catch (MetacatInaccessibleException mie) {
85
			System.err.println("Metacat is: " + metacatUrl);
86
			fail("Metacat connection failed." + mie.getMessage());
87
		}
88
	}
89

    
90
	/**
91
	 * Release any objects after tests are complete
92
	 */
93
	public void tearDown() {
94
	}
95

    
96
	/**
97
	 * Create a suite of tests to be run together
98
	 */
99
	public static Test suite() {
100
		TestSuite suite = new TestSuite();
101
		suite.addTest(new SyncAccessPolicyTest("initialize"));
102
		suite.addTest(new SyncAccessPolicyTest("testIsEqual"));
103
		suite.addTest(new SyncAccessPolicyTest("testSyncAccessPolicy"));
104

    
105
		return suite;
106
	}
107

    
108
	/**
109
	 * Run an initial test that always passes to check that the test harness is
110
	 * working.
111
	 */
112
	public void initialize() {
113
		assertTrue(1 == 1);
114
	}
115

    
116
	/**
117
	 * constructs a "fake" session with a test subject
118
	 * @return
119
	 */
120
	@Override
121
	public Session getTestSession() throws Exception {
122
		Session session = new Session();
123
        Subject subject = new Subject();
124
        subject.setValue(anotheruser);
125
        session.setSubject(subject);
126
        return session;
127
	}
128
	/**
129
	 * Test object creation
130
	 */
131
	public Identifier createTestPid() {
132
		printTestHeader("testCreate");
133
		Identifier pid = null;
134
		try {
135
			Session session = getTestSession();
136
			Identifier guid = new Identifier();
137
			guid.setValue("testSyncAP." + System.currentTimeMillis());
138
			InputStream object = new ByteArrayInputStream(
139
					"test".getBytes("UTF-8"));
140
			SystemMetadata sysmeta = createSystemMetadata(guid,
141
					session.getSubject(), object);
142

    
143
			pid = MNodeService.getInstance(request).create(session, guid,
144
					object, sysmeta);
145
		} catch (Exception e) {
146
			e.printStackTrace();
147
			debug("Error creating pid: " + e.getMessage());
148
			fail();
149
		}
150
		return pid;
151
	}
152

    
153
	public void testSyncAccessPolicy() {
154

    
155
		AccessPolicy cnAccessPolicy = null;
156
		AccessPolicy mnAccessPolicy = null;
157
		SystemMetadata cnSysMeta = null;
158
		SystemMetadata mnSysMeta = null;
159
		String resultXML = null;
160

    
161
		String response = null;
162
		debug("Logging in with user: " + anotheruser + ", password: "
163
				+ anotherpassword);
164
		try {
165
			response = m.login(anotheruser, anotherpassword);
166
			debug("Login response: " + response);
167
		} catch (Exception e) {
168
			debug("Unable to login: " + response);
169
			fail();
170
		}
171

    
172
		try {
173
			debug("\nStarting sync access policy test");
174

    
175
			Identifier pid = null;
176
			// create the systemMetadata the normal way
177

    
178
			pid = createTestPid();
179
			assertNotNull(pid);
180

    
181
			debug("Inserted new document: " + pid.getValue());
182
			try {
183
				// Get sm, access policy for requested localId
184
				mnSysMeta = IdentifierManager.getInstance().getSystemMetadata(
185
						pid.getValue());
186
			} catch (Exception e) {
187
				debug("Error getting system metadata for new pid: "
188
						+ pid.getValue() + ". Message: " + e.getMessage());
189
				fail();
190
			}
191

    
192
			CNode cn = null;
193

    
194
			try {
195
				cn = D1Client.getCN();
196
			} catch (ServiceFailure sf) {
197
				debug("Unable to get Coordinating node name for this MN");
198
				fail();
199
			}
200

    
201
			boolean found = false;
202
			int attempts = 0;
203

    
204
			// We have to wait until the CN has harvested the new document,
205
			// otherwise we
206
			// will just get an error of "pid not found" when we request the CN
207
			// to
208
			// sync the access policies
209
			// (which is triggered by the Metacat setaccess call).
210

    
211
			debug("Checking for new docid on CN...");
212
			found = false;
213
			for (int i = 0; i < 6; i++) {
214
				attempts = i;
215
				Thread.sleep(1000 * 60);
216
				// Get the test document from the CN
217
				// Get sm, access policy for requested pid from the CN
218
				try {
219
					cnSysMeta = cn.getSystemMetadata(pid);
220
				} catch (Exception e) {
221
					debug("Error getting system metadata for pid: "
222
							+ pid.getValue() + " from cn: " + e.getMessage());
223
					debug("Will request pid from CN again...");
224
					continue;
225
				}
226

    
227
				found = true;
228
				debug("Document " + pid.getValue() + " has been read from CN.");
229
				break;
230
			}
231

    
232
			if (!found) {
233
				fail("Error, cannot read system metadata for pid: " + pid
234
						+ " after " + attempts + " attempts");
235
			}
236

    
237
			Hashtable<String, String[]> fieldValuePairs = new Hashtable<String, String[]>();
238
			fieldValuePairs = new Hashtable<String, String[]>();
239

    
240
			String localId = null;
241
			try {
242
				localId = IdentifierManager.getInstance().getLocalId(
243
						pid.getValue());
244
			} catch (Exception e) {
245
				debug("Unable to retrieve localId for pid: " + pid.getValue());
246
				fail();
247
			}
248

    
249
			debug("Updating permissions of localId: " + localId + ", guid: "
250
					+ pid.getValue() + ", username: " + username + " read, allow, allowFirst");
251

    
252
			try {
253
				response = m.setAccess(localId, username, 
254
						AccessControlInterface.READSTRING, 
255
	    				AccessControlInterface.ALLOW, 
256
	    				AccessControlInterface.ALLOWFIRST);
257
			} catch (Exception e) {
258
				debug("Response from setaccess: " + response);
259
				debug("Error setting access for localId: " + e.getMessage());
260
				fail();
261
			}
262
			
263
			debug("Response from setaccess: " + response);
264
			debug("Retrieving updated docid from CN to check if perms were updated...");
265

    
266
			// Get the test document from the CN
267
			// Get sm, access policy for requested pid from the CN
268
			try {
269
				cnSysMeta = cn.getSystemMetadata(pid);
270
			} catch (Exception e) {
271
				debug("Error getting system metadata for pid: "
272
						+ pid.getValue() + " from cn: " + e.getMessage());
273
				fail();
274
			}
275

    
276
			debug("Checking privs retrieved from CN");
277
			// Check if privs for the new user showed up on the CN
278
			mnAccessPolicy = mnSysMeta.getAccessPolicy();
279
			debug("Getting access policy for pid: " + pid.getValue());
280
			cnAccessPolicy = cnSysMeta.getAccessPolicy();
281
			debug("Diffing access policies (MN,CN) for pid: " + pid.getValue());
282
			SyncAccessPolicy syncAP = new SyncAccessPolicy();
283
			debug("Comparing access policies...");
284
			
285
			Boolean apEqual = new Boolean (syncAP.isEqual(mnAccessPolicy, cnAccessPolicy));
286
			debug("Access policies are equal is " + apEqual.toString());
287
			assert (apEqual == true);
288

    
289
			m.logout();
290

    
291
		} catch (Exception e) {
292
			e.printStackTrace();
293
			fail("Error running syncAP test: " + e.getMessage());
294
		}
295

    
296
		debug("Done running testSyncAccessPolicy");
297
	}
298
	
299
	public void testIsEqual() {
300
		AccessPolicy ap1 = new AccessPolicy();
301
		AccessRule ar1 = new AccessRule();
302
		ar1.addPermission(Permission.READ);
303
		Subject subject1 = new Subject();
304
		subject1.setValue(username);
305
		ar1.addSubject(subject1);
306
		ap1.addAllow(ar1);
307
		
308
		AccessPolicy ap2 = new AccessPolicy();
309
		AccessRule ar2 = new AccessRule();
310
		ar2.addPermission(Permission.READ);
311
		Subject subject2 = new Subject();
312
		subject2.setValue(username);
313
		ar2.addSubject(subject2);
314
		ap2.addAllow(ar2);
315
		
316
		boolean isEqual = false;
317
		SyncAccessPolicy syncAP = new SyncAccessPolicy();
318
		
319
		// try something that should be true
320
		isEqual = syncAP.isEqual(ap1, ap2);
321
		assertTrue(isEqual);
322
		
323
		// try something that makes them not equal
324
		Subject subject3 = new Subject();
325
		subject3.setValue(anotheruser);
326
		ar2.addSubject(subject3);
327
		
328
		isEqual = syncAP.isEqual(ap1, ap2);
329
		assertFalse(isEqual);
330
		
331
		isEqual = syncAP.isEqual(ap1, null);
332
		assertFalse(isEqual);
333
	}
334
}
(2-2/2)