001 /*
002 * GroupImpl.java
003 *
004 * Copyright (c) 1995-2010, The University of Sheffield. See the file
005 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006 *
007 * This file is part of GATE (see http://gate.ac.uk/), and is free
008 * software, licenced under the GNU Library General Public License,
009 * Version 2, June 1991 (in the distribution as file licence.html,
010 * and also available at http://gate.ac.uk/gate/licence.html).
011 *
012 * Marin Dimitrov, 19/Sep/2001
013 *
014 * $Id: GroupImpl.java 12006 2009-12-01 17:24:28Z thomas_heitz $
015 */
016
017 package gate.security;
018
019 import java.sql.*;
020 import java.util.List;
021 import java.util.Vector;
022
023 import junit.framework.Assert;
024
025 import gate.Gate;
026 import gate.event.*;
027 import gate.persist.DBHelper;
028 import gate.persist.PersistenceException;
029 import gate.util.MethodNotImplementedException;
030
031
032 public class GroupImpl
033 implements Group, ObjectModificationListener {
034
035 /** --- */
036 private Long id;
037
038 /** --- */
039 private String name;
040
041 /** --- */
042 private List users;
043
044 /** --- */
045 private Connection conn;
046 /** --- */
047 private int dbType;
048
049 /** --- */
050 private AccessControllerImpl ac;
051
052 /** --- */
053 private Vector omModificationListeners;
054 /** --- */
055 private Vector omCreationListeners;
056 /** --- */
057 private Vector omDeletionListeners;
058
059
060
061 public GroupImpl(Long id, String name, List users,AccessControllerImpl ac,Connection conn) {
062
063 this.id = id;
064 this.name = name;
065 this.users = users;
066 this.ac = ac;
067 this.conn = conn;
068
069 try {
070 String jdbcURL = conn.getMetaData().getURL();
071 this.dbType = DBHelper.getDatabaseType(jdbcURL);
072 Assert.assertTrue(this.dbType == DBHelper.ORACLE_DB ||
073 this.dbType == DBHelper.POSTGRES_DB);
074 }
075 catch(SQLException sqex) {
076 sqex.printStackTrace();
077 }
078
079 this.omModificationListeners = new Vector();
080 this.omCreationListeners = new Vector();
081 this.omDeletionListeners = new Vector();
082
083 //register self as listener for the security factory events
084 //of type OBJECT_DELETED (users)
085 //don't forget that only AC can delete users, so he's the only
086 //source of such events
087 this.ac.registerObjectModificationListener(
088 this,
089 ObjectModificationEvent.OBJECT_DELETED);
090
091 }
092
093 /** --- */
094 public Long getID() {
095
096 return id;
097 }
098
099 /** --- */
100 public String getName() {
101
102 return name;
103 }
104
105 /** --- */
106 public List getUsers() {
107
108 /** NOTE that we're returning a copy of the actuall collection of users
109 * so that someone would not accidentaly modify it */
110 Vector copy = new Vector();
111 copy.addAll(this.users);
112 return copy;
113
114 }
115
116
117 /** --- */
118 public void setName(String newName, Session s)
119 throws PersistenceException,SecurityException {
120
121 //first check the session and then check whether the user is member of the group
122 if (this.ac.isValidSession(s) == false) {
123 throw new SecurityException("invalid session supplied");
124 }
125
126 //2.1 check if the user is privileged
127 if (false == s.isPrivilegedSession() ) {
128 throw new SecurityException("insufficient privileges to change group name");
129 }
130
131 CallableStatement stmt = null;
132 PreparedStatement pstmt = null;
133
134 //Oracle / Postgres ?
135
136 if (this.dbType == DBHelper.ORACLE_DB) {
137
138 //1. update database
139 try {
140
141 stmt = this.conn.prepareCall(
142 "{ call "+Gate.DB_OWNER+".security.set_group_name(?,?)} ");
143 stmt.setLong(1,this.id.longValue());
144 stmt.setString(2,newName);
145 stmt.execute();
146 //release stmt???
147 }
148 catch(SQLException sqle) {
149 throw new PersistenceException("can't change group name in DB: ["+ sqle.getMessage()+"]");
150 }
151 finally {
152 DBHelper.cleanup(stmt);
153 }
154 }
155
156 else if (this.dbType == DBHelper.POSTGRES_DB) {
157
158 try {
159
160 String sql = "select security_set_group_name(?,?) ";
161 pstmt = this.conn.prepareStatement(sql);
162 pstmt.setLong(1,this.id.longValue());
163 pstmt.setString(2,newName);
164 pstmt.execute();
165 //release stmt???
166 }
167 catch(SQLException sqle) {
168 throw new PersistenceException("can't change group name in DB: ["+ sqle.getMessage()+"]");
169 }
170 finally {
171 DBHelper.cleanup(pstmt);
172 }
173
174 }
175
176 else {
177 throw new IllegalArgumentException();
178 }
179
180 //2. update memebr variable
181 this.name = newName;
182
183 //3. create ObjectModificationEvent
184 ObjectModificationEvent e = new ObjectModificationEvent(
185 this,
186 ObjectModificationEvent.OBJECT_MODIFIED,
187 Group.OBJECT_CHANGE_NAME);
188
189
190 //4. fire ObjectModificationEvent for all who care
191 this.fireObjectModifiedEvent(e);
192
193 }
194
195
196 /** --- */
197 public void addUser(Long userID, Session s)
198 throws PersistenceException,SecurityException{
199
200 User usr = this.ac.findUser(userID);
201 addUser(usr,s);
202 }
203
204 /** --- */
205 public void addUser(User usr, Session s)
206 throws PersistenceException,SecurityException{
207
208 //1. check if the user is not already in group
209 if (this.users.contains(usr)) {
210 throw new SecurityException("User id=["+usr.getID()+"] is alredy member of group");
211 }
212
213 //2. check the session
214 if (false == this.ac.isValidSession(s)) {
215 throw new SecurityException("invalid session provided");
216 }
217
218 //2.1 check if the user is privileged
219 if (false == s.isPrivilegedSession() ) {
220 throw new SecurityException("insufficient privileges to add users");
221 }
222
223 //3. update DB
224 CallableStatement stmt = null;
225 PreparedStatement pstmt = null;
226
227 //Oracle / Postgres ?
228
229 if (this.dbType == DBHelper.ORACLE_DB) {
230
231 try {
232 stmt = this.conn.prepareCall(
233 "{ call "+Gate.DB_OWNER+".security.add_user_to_group(?,?)} ");
234 stmt.setLong(1,this.id.longValue());
235 stmt.setLong(2,usr.getID().longValue());
236 stmt.execute();
237 //release stmt???
238 }
239 catch(SQLException sqle) {
240 throw new PersistenceException("can't add user to group in DB: ["+ sqle.getMessage()+"]");
241 }
242 finally {
243 DBHelper.cleanup(stmt);
244 }
245 }
246
247 else if (this.dbType == DBHelper.POSTGRES_DB) {
248
249 try {
250 String sql = "select security_add_user_to_group(?,?) ";
251 pstmt = this.conn.prepareStatement(sql);
252 pstmt.setLong(1,this.id.longValue());
253 pstmt.setLong(2,usr.getID().longValue());
254 pstmt.execute();
255 //release stmt???
256 }
257 catch(SQLException sqle) {
258 throw new PersistenceException("can't add user to group in DB: ["+ sqle.getMessage()+"]");
259 }
260 finally {
261 DBHelper.cleanup(pstmt);
262 }
263
264 }
265
266 else {
267 throw new IllegalArgumentException();
268 }
269
270
271 //4. create ObjectModificationEvent
272 ObjectModificationEvent e = new ObjectModificationEvent(
273 this,
274 ObjectModificationEvent.OBJECT_MODIFIED,
275 Group.OBJECT_CHANGE_ADDUSER);
276
277 //5. update usr collection
278 this.users.add(usr);
279
280 //6. notify user about the change
281 ((ObjectModificationListener)usr).objectModified(e);
282
283 //7. fire ObjectModificationEvent for all other who care
284 fireObjectModifiedEvent(e);
285 }
286
287
288 /** --- */
289 public void removeUser(Long userID, Session s)
290 throws PersistenceException,SecurityException {
291
292
293 User usr = this.ac.findUser(userID);
294 removeUser(usr,s);
295 }
296
297
298 /** --- */
299 public void removeUser(User usr, Session s)
300 throws PersistenceException,SecurityException{
301
302 //1. check if the user member of group
303 if (this.users.contains(usr) == false) {
304 throw new SecurityException("User id=["+usr.getID()+"] is NOT a member of group");
305 }
306
307 //2. check the session
308 if (this.ac.isValidSession(s) == false) {
309 throw new SecurityException("invalid session provided");
310 }
311
312 //2.1 check if the user is privileged
313 if (false == s.isPrivilegedSession() ) {
314 throw new SecurityException("insufficient privileges to remove users");
315 }
316
317 //3. update DB
318 CallableStatement stmt = null;
319 PreparedStatement pstmt = null;
320
321 //Oracle / Postgres ?
322
323 if (this.dbType == DBHelper.ORACLE_DB) {
324 try {
325 stmt = this.conn.prepareCall(
326 "{ call "+Gate.DB_OWNER+".security.remove_user_from_group(?,?)} ");
327 stmt.setLong(1,this.id.longValue());
328 stmt.setLong(2,usr.getID().longValue());
329 stmt.execute();
330 //release stmt???
331 }
332 catch(SQLException sqle) {
333 throw new PersistenceException("can't remove user from group in DB: ["+ sqle.getMessage()+"]");
334 }
335 finally {
336 DBHelper.cleanup(stmt);
337 }
338 }
339
340 else if (this.dbType == DBHelper.POSTGRES_DB) {
341 try {
342 String sql = "select security_remove_user_from_group(?,?) ";
343 pstmt = this.conn.prepareStatement(sql);
344 pstmt.setLong(1,this.id.longValue());
345 pstmt.setLong(2,usr.getID().longValue());
346 pstmt.execute();
347 //release stmt???
348 }
349 catch(SQLException sqle) {
350 throw new PersistenceException("can't remove user from group in DB: ["+ sqle.getMessage()+"]");
351 }
352 finally {
353 DBHelper.cleanup(pstmt);
354 }
355 }
356
357 else {
358 throw new IllegalArgumentException();
359 }
360
361 //4. create ObjectModificationEvent
362 ObjectModificationEvent e = new ObjectModificationEvent(
363 this,
364 ObjectModificationEvent.OBJECT_MODIFIED,
365 Group.OBJECT_CHANGE_REMOVEUSER);
366
367 //5. update usr collection
368 this.users.remove(usr);
369
370 //6. notify user about the change
371 ((ObjectModificationListener)usr).objectModified(e);
372
373 //7. fire ObjectModificationEvent for all other who care
374 fireObjectModifiedEvent(e);
375 }
376
377
378 //ObjectModificationListener interface
379 public void objectCreated(ObjectModificationEvent e) {
380
381 //ignore, we don't care about creations
382 return;
383 }
384
385 public void objectModified(ObjectModificationEvent e) {
386
387 //ignore, we don't care about modifications
388 return;
389 }
390
391 public void objectDeleted(ObjectModificationEvent e) {
392
393 if (e.getSource() instanceof User) {
394
395 User usr = (User)e.getSource();
396 //check if the user being deleted is one we contain
397 if (true == this.users.contains(usr)) {
398 this.users.remove(usr);
399 }
400
401 }
402 }
403
404 public void processGateEvent(GateEvent e){
405 throw new MethodNotImplementedException();
406 }
407
408
409 /**
410 *
411 * this one is necessary for the contains() operations in Lists
412 * It is possible that two users have two different GroupImpl that refer
413 * to the very same GATE group in the DB, because they got it from the security
414 * factory at different times. So we assume that two instances refer the same
415 * GATE group if NAME1==NAME2
416 *
417 * */
418 public boolean equals(Object obj)
419 {
420 Assert.assertTrue(obj instanceof Group);
421
422 Group group2 = (Group)obj;
423
424 return (this.id.equals(group2.getID()));
425 }
426
427
428 public void registerObjectModificationListener(ObjectModificationListener l,
429 int eventType) {
430
431 if (eventType != ObjectModificationEvent.OBJECT_CREATED &&
432 eventType != ObjectModificationEvent.OBJECT_DELETED &&
433 eventType != ObjectModificationEvent.OBJECT_MODIFIED) {
434
435 throw new IllegalArgumentException();
436 }
437
438 switch(eventType) {
439 case ObjectModificationEvent.OBJECT_CREATED :
440 //we never generate such events
441 Assert.fail();
442 // this.omCreationListeners.add(l);
443 break;
444 case ObjectModificationEvent.OBJECT_DELETED :
445 //we never generate such events
446 Assert.fail();
447 // this.omDeletionListeners.add(l);
448 break;
449 case ObjectModificationEvent.OBJECT_MODIFIED :
450 this.omModificationListeners.add(l);
451 break;
452 default:
453 Assert.fail();
454 }
455
456 }
457
458 private void fireObjectModifiedEvent(ObjectModificationEvent e) {
459
460 //sanity check
461 if (e.getType() != ObjectModificationEvent.OBJECT_MODIFIED) {
462 throw new IllegalArgumentException();
463 }
464
465 for (int i=0; i< this.omModificationListeners.size(); i++) {
466 ((ObjectModificationListener)omModificationListeners.elementAt(i)).objectModified(e);
467 }
468 }
469
470 public void unregisterObjectModificationListener(ObjectModificationListener l,
471 int eventType) {
472
473 if (eventType != ObjectModificationEvent.OBJECT_CREATED &&
474 eventType != ObjectModificationEvent.OBJECT_DELETED &&
475 eventType != ObjectModificationEvent.OBJECT_MODIFIED) {
476
477 throw new IllegalArgumentException();
478 }
479
480 switch(eventType) {
481 case ObjectModificationEvent.OBJECT_CREATED :
482 this.omCreationListeners.remove(l);
483 break;
484 case ObjectModificationEvent.OBJECT_DELETED :
485 this.omDeletionListeners.remove(l);
486 break;
487 case ObjectModificationEvent.OBJECT_MODIFIED :
488 this.omModificationListeners.remove(l);
489 break;
490 default:
491 Assert.fail();
492 }
493 }
494
495 /*package*/ void setUsers(Vector userIDs) {
496
497 for (int i=0; i< userIDs.size(); i++) {
498 Long usr_id = (Long)userIDs.elementAt(i);
499 User usr = null;
500
501 try {
502 usr = (User)this.ac.findUser(usr_id);
503 }
504 catch(SecurityException se) {
505 Assert.fail();
506 }
507 catch(PersistenceException se) {
508 Assert.fail();
509 }
510
511 //is valid?
512 Assert.assertNotNull(usr);
513 Assert.assertTrue(usr instanceof User);
514 //add to our collection, which was empty so far
515 this.users.add(usr);
516 }
517
518
519 }
520
521 }
|