001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/security/drm/SecurityTransaction.java $
002    /*----------------------------------------------------------------------------
003     This file is part of deegree, http://deegree.org/
004     Copyright (C) 2001-2009 by:
005       Department of Geography, University of Bonn
006     and
007       lat/lon GmbH
008    
009     This library is free software; you can redistribute it and/or modify it under
010     the terms of the GNU Lesser General Public License as published by the Free
011     Software Foundation; either version 2.1 of the License, or (at your option)
012     any later version.
013     This library is distributed in the hope that it will be useful, but WITHOUT
014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016     details.
017     You should have received a copy of the GNU Lesser General Public License
018     along with this library; if not, write to the Free Software Foundation, Inc.,
019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020    
021     Contact information:
022    
023     lat/lon GmbH
024     Aennchenstr. 19, 53177 Bonn
025     Germany
026     http://lat-lon.de/
027    
028     Department of Geography, University of Bonn
029     Prof. Dr. Klaus Greve
030     Postfach 1147, 53001 Bonn
031     Germany
032     http://www.geographie.uni-bonn.de/deegree/
033    
034     e-mail: info@deegree.org
035    ----------------------------------------------------------------------------*/
036    package org.deegree.security.drm;
037    
038    import static org.deegree.security.drm.SecurityAccessManager.getInstance;
039    import static org.deegree.security.drm.model.Privilege.ADDOBJECT;
040    
041    import java.util.ArrayList;
042    import java.util.HashSet;
043    import java.util.Iterator;
044    import java.util.List;
045    
046    import org.deegree.framework.util.StringPair;
047    import org.deegree.security.GeneralSecurityException;
048    import org.deegree.security.UnauthorizedException;
049    import org.deegree.security.drm.model.Group;
050    import org.deegree.security.drm.model.Privilege;
051    import org.deegree.security.drm.model.Right;
052    import org.deegree.security.drm.model.RightSet;
053    import org.deegree.security.drm.model.RightType;
054    import org.deegree.security.drm.model.Role;
055    import org.deegree.security.drm.model.SecurableObject;
056    import org.deegree.security.drm.model.SecuredObject;
057    import org.deegree.security.drm.model.Service;
058    import org.deegree.security.drm.model.User;
059    
060    /**
061     *
062     *
063     *
064     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
065     * @author last edited by: $Author: mschneider $
066     *
067     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
068     */
069    public class SecurityTransaction extends SecurityAccess {
070    
071        private Role adminRole;
072    
073        private long timestamp;
074    
075        /**
076         * @param user
077         * @param registry
078         * @param adminRole
079         */
080        SecurityTransaction( User user, SecurityRegistry registry, Role adminRole ) {
081            super( user, registry );
082            this.adminRole = adminRole;
083            this.timestamp = System.currentTimeMillis();
084        }
085    
086        /**
087         * Returns the conjunction of an array of roles plus a single role.
088         *
089         * @param roles
090         * @param role
091         * @return the conjunction of an array of roles plus a single role.
092         */
093        public Role[] addRoles( Role[] roles, Role role ) {
094            HashSet<Role> roleSet = new HashSet<Role>( roles.length + 1 );
095            roleSet.add( role );
096            for ( int i = 0; i < roles.length; i++ ) {
097                roleSet.add( roles[i] );
098            }
099            return roleSet.toArray( new Role[roleSet.size()] );
100        }
101    
102        /**
103         * Deletes all data from the underlying <code>Registry</code> and sets the default objects (SEC_ADMIN user, role and
104         * group) and standard rights and privileges.
105         *
106         * @throws GeneralSecurityException
107         */
108        public void clean()
109                                throws GeneralSecurityException {
110            SecurityAccessManager.getInstance().verify( this );
111            registry.clean( this );
112        }
113    
114        /**
115         * Removes a <code>Group</code> from the <code>Registry</code>.
116         *
117         * This means:
118         * <ul>
119         * <li>owner role ($G:GROUPNAME) is removed
120         * <li>group is removed
121         * </ul>
122         *
123         * NOTE: Only performed if the acting user has the 'delete'-right on the group object.
124         *
125         * @param group
126         * @throws GeneralSecurityException
127         * @throws UnauthorizedException
128         */
129        public void deregisterGroup( Group group )
130                                throws GeneralSecurityException, UnauthorizedException {
131            SecurityAccessManager.getInstance().verify( this );
132            checkForRight( RightType.DELETE, group );
133            try {
134                Role ownerRole = registry.getRoleByName( this, "$G:" + group.getName() );
135                registry.deregisterRole( this, ownerRole );
136            } catch ( UnknownException e ) {
137            }
138            registry.deregisterGroup( this, group );
139        }
140    
141        /**
142         * Removes a <code>Role</code> from the <code>Registry</code>.
143         *
144         * This means:
145         * <ul>
146         * <li>owner role ($R:ROLENAME) is removed
147         * <li>role is removed
148         * </ul>
149         *
150         * NOTE: Only performed if acting user has the 'delete'-right on the role object.
151         *
152         * @param role
153         * @throws GeneralSecurityException
154         * @throws UnauthorizedException
155         */
156        public void deregisterRole( Role role )
157                                throws GeneralSecurityException, UnauthorizedException {
158            SecurityAccessManager.getInstance().verify( this );
159            checkForRight( RightType.DELETE, role );
160            try {
161                Role ownerRole = registry.getRoleByName( this, "$R:" + role.getName() );
162                registry.deregisterRole( this, ownerRole );
163            } catch ( UnknownException e ) {
164            }
165            registry.deregisterRole( this, role );
166        }
167    
168        /**
169         * Removes a <code>SecuredObject</code> from the <code>Registry</code>.
170         *
171         * This means:
172         * <ul>
173         * <li>owner role ($O:OBJECTNAME) is removed
174         * <li>object is removed
175         * </ul>
176         *
177         * NOTE: Only performed if acting user has the 'delete'-right on the secured object.
178         *
179         * @param object
180         * @throws GeneralSecurityException
181         * @throws UnauthorizedException
182         */
183        public void deregisterSecuredObject( SecuredObject object )
184                                throws GeneralSecurityException, UnauthorizedException {
185            SecurityAccessManager.getInstance().verify( this );
186            checkForRight( RightType.DELETE, object );
187            try {
188                Role ownerRole = registry.getRoleByName( this, "$O:" + object.getName() );
189                registry.deregisterRole( this, ownerRole );
190            } catch ( UnknownException e ) {
191            }
192            registry.deregisterSecuredObject( this, object );
193        }
194    
195        /**
196         * Removes a <code>User</code> from the <code>Registry</code>.
197         *
198         * This means:
199         * <ul>
200         * <li>owner role ($U:USERNAME) is removed
201         * <li>user is removed
202         * </ul>
203         *
204         * NOTE: Only performed if acting user has the 'delete'-right on the user object.
205         *
206         * @param user
207         * @throws GeneralSecurityException
208         * @throws UnauthorizedException
209         */
210        public void deregisterUser( User user )
211                                throws GeneralSecurityException, UnauthorizedException {
212            SecurityAccessManager.getInstance().verify( this );
213            checkForRight( RightType.DELETE, user );
214            try {
215                Role ownerRole = registry.getRoleByName( this, "$U:" + user.getName() );
216                registry.deregisterRole( this, ownerRole );
217            } catch ( UnknownException e ) {
218                e.printStackTrace();
219            }
220            registry.deregisterUser( this, user );
221        }
222    
223        /**
224         *
225         * @return timestamp
226         */
227        public long getTimestamp() {
228            return timestamp;
229        }
230    
231        /**
232         * Registers a new <code>Group</code> to the <code>Registry</code>.
233         *
234         * This means:
235         * <ul>
236         * <li>a group is created in the registry
237         * <li>a corresponding owner role is created: $G:GROUPNAME
238         * <li>rights for the owner role are set up; creator has delete, update and grant rights on the group, administrator
239         * role gets these right, too
240         * </ul>
241         *
242         * NOTE: Only performed if acting user has the 'addgroup'-privilege.
243         *
244         * @param name
245         * @param title
246         * @return the new Group
247         * @throws GeneralSecurityException
248         */
249        public Group registerGroup( String name, String title )
250                                throws GeneralSecurityException {
251            SecurityAccessManager.getInstance().verify( this );
252            checkForPrivilege( Privilege.ADDGROUP );
253            if ( name.startsWith( "$" ) ) {
254                throw new GeneralSecurityException( "Groupname '" + name + "' is invalid. The '$'-character is for "
255                                                    + "internal use only." );
256            }
257            Group group = registry.registerGroup( this, name, title );
258            // only add owner role if lock holder is not the administrator
259            if ( this.user.getID() != User.ID_SEC_ADMIN ) {
260                Role ownerRole = registry.registerRole( this, "$G:" + name );
261                registry.setRolesForUser( this, user, addRoles( registry.getRolesForUser( this, user ), ownerRole ) );
262                registry.setRights( this, group, ownerRole, new Right[] { new Right( group, RightType.DELETE ),
263                                                                         new Right( group, RightType.UPDATE ),
264                                                                         new Right( group, RightType.GRANT ) } );
265            }
266            registry.setRights( this, group, adminRole, new Right[] { new Right( group, RightType.DELETE ),
267                                                                     new Right( group, RightType.UPDATE ),
268                                                                     new Right( group, RightType.GRANT ) } );
269            return group;
270        }
271    
272        /**
273         * Registers a new <code>Role</code> to the <code>Registry</code>.
274         *
275         * This means:
276         * <ul>
277         * <li>a role is created in the registry
278         * <li>a corresponding owner role is created: $R:ROLENAME
279         * <li>rights for the owner role are set up; creator has delete, update and grant rights on the role, administrator
280         * role gets these right, too
281         * </ul>
282         *
283         * NOTE: Only performed if acting user has the 'addrole'-privilege.
284         *
285         * @param name
286         * @return the new Role
287         * @throws GeneralSecurityException
288         */
289        public Role registerRole( String name )
290                                throws GeneralSecurityException {
291            SecurityAccessManager.getInstance().verify( this );
292            checkForPrivilege( Privilege.ADDROLE );
293            if ( name.startsWith( "$" ) ) {
294                throw new GeneralSecurityException( "Rolename '" + name + "' is invalid. The '$'-character is for "
295                                                    + "internal use only." );
296            }
297    
298            Role role = registry.registerRole( this, name );
299            if ( this.user.getID() != User.ID_SEC_ADMIN ) {
300                Role ownerRole = registry.registerRole( this, "$R:" + name );
301                registry.setRolesForUser( this, user, addRoles( registry.getRolesForUser( this, user ), ownerRole ) );
302                registry.setRights( this, role, ownerRole, new Right[] { new Right( role, RightType.DELETE ),
303                                                                        new Right( role, RightType.UPDATE ),
304                                                                        new Right( role, RightType.GRANT ) } );
305            }
306            registry.setRights( this, role, adminRole, new Right[] { new Right( role, RightType.DELETE ),
307                                                                    new Right( role, RightType.UPDATE ),
308                                                                    new Right( role, RightType.GRANT ) } );
309            return role;
310        }
311    
312        /**
313         * Registers a new <code>SecuredObject</code> to the <code>Registry</code>.
314         *
315         * This means:
316         * <ul>
317         * <li>a secured object is created in the registry
318         * <li>a corresponding owner role is created: $O:OBJECTNAME
319         * <li>rights for the owner role are set up; creator has delete, update and grant rights on the object,
320         * administrator role gets these right, too
321         * </ul>
322         *
323         * @param type
324         * @param name
325         * @param title
326         * @return the new SecuredObject
327         * @throws GeneralSecurityException
328         */
329        public SecuredObject registerSecuredObject( String type, String name, String title )
330                                throws GeneralSecurityException {
331            SecurityAccessManager.getInstance().verify( this );
332            checkForPrivilege( Privilege.ADDOBJECT );
333            if ( name.startsWith( "$" ) ) {
334                throw new GeneralSecurityException( "Objectname '" + name + "' is invalid. The '$'-character is for "
335                                                    + "internal use only." );
336            }
337            SecuredObject object = registry.registerSecuredObject( this, type, name, title );
338            if ( this.user.getID() != User.ID_SEC_ADMIN ) {
339                Role ownerRole = registry.registerRole( this, "$O:" + name );
340                registry.setRolesForUser( this, user, addRoles( registry.getRolesForUser( this, user ), ownerRole ) );
341                registry.setRights( this, object, ownerRole, new Right[] { new Right( object, RightType.DELETE ),
342                                                                          new Right( object, RightType.UPDATE ),
343                                                                          new Right( object, RightType.GRANT ) } );
344            }
345            registry.setRights( this, object, adminRole, new Right[] { new Right( object, RightType.DELETE ),
346                                                                      new Right( object, RightType.UPDATE ),
347                                                                      new Right( object, RightType.GRANT ) } );
348            return object;
349        }
350    
351        /**
352         * Registers a new <code>User</code> to the <code>Registry</code>.
353         *
354         * This means:
355         * <ul>
356         * <li>a user is created in the registry
357         * <li>a corresponding owner role is created: $U:USERNAME
358         * <li>rights for the owner role are set up; creator has delete, update and grant rights on the user, administrator
359         * role gets these right, too
360         * </ul>
361         *
362         * NOTE: Only performed if acting user has the 'adduser'-privilege.
363         *
364         * @param name
365         * @param password
366         *            null means that password checking is disabled
367         * @param lastName
368         * @param firstName
369         * @param mailAddress
370         * @return the new User
371         * @throws GeneralSecurityException
372         */
373        public User registerUser( String name, String password, String lastName, String firstName, String mailAddress )
374                                throws GeneralSecurityException {
375            SecurityAccessManager.getInstance().verify( this );
376            checkForPrivilege( Privilege.ADDUSER );
377            if ( name.startsWith( "$" ) ) {
378                throw new GeneralSecurityException( "Username '" + name + "' is invalid. The '$'-character is for "
379                                                    + "internal use only." );
380            }
381            User user = registry.registerUser( this, name, password, lastName, firstName, mailAddress );
382    
383            // only add owner role if lock holder is not the administrator
384            if ( this.user.getID() != User.ID_SEC_ADMIN ) {
385                Role ownerRole = registry.registerRole( this, "$U:" + name );
386                registry.setRolesForUser( this, user, addRoles( registry.getRolesForUser( this, user ), ownerRole ) );
387                registry.setRights( this, user, ownerRole, new Right[] { new Right( user, RightType.DELETE ),
388                                                                        new Right( user, RightType.UPDATE ),
389                                                                        new Right( user, RightType.GRANT ) } );
390            }
391            registry.setRights( this, user, adminRole, new Right[] { new Right( user, RightType.DELETE ),
392                                                                    new Right( user, RightType.UPDATE ),
393                                                                    new Right( user, RightType.GRANT ) } );
394            return user;
395        }
396    
397        /**
398         * Updates the data of an existing <code>User</code> in the <code>Registry</code>.
399         *
400         * NOTE: Only performed if acting user has the 'update'-right on the user.
401         *
402         * @param user
403         * @throws GeneralSecurityException
404         */
405        public void updateUser( User user )
406                                throws GeneralSecurityException {
407            SecurityAccessManager.getInstance().verify( this );
408            checkForRight( RightType.UPDATE, user );
409            registry.updateUser( this, user );
410        }
411    
412        /**
413         * Sets the <code>Group</code> s that a given <code>Group</code> is a DIRECT member of.
414         *
415         * NOTE: Only performed if the acting user has the 'grant'-right for all the groups that are requested to be added /
416         * removed.
417         *
418         * @param group
419         * @param newGroups
420         * @throws GeneralSecurityException
421         * @throws UnauthorizedException
422         */
423        public void setGroupsForGroup( Group group, Group[] newGroups )
424                                throws GeneralSecurityException, UnauthorizedException {
425            SecurityAccessManager.getInstance().verify( this );
426            Group[] oldGroups = group.getGroups( this );
427    
428            // build set for old groups
429            HashSet<Group> oldGroupSet = new HashSet<Group>( oldGroups.length );
430            for ( int i = 0; i < oldGroups.length; i++ ) {
431                oldGroupSet.add( oldGroups[i] );
432            }
433            // build set for new groups
434            HashSet<Group> newGroupSet = new HashSet<Group>( oldGroups.length );
435            for ( int i = 0; i < newGroups.length; i++ ) {
436                newGroupSet.add( newGroups[i] );
437            }
438    
439            // check grant right for all groups requested to be removed
440            Iterator it = oldGroupSet.iterator();
441            while ( it.hasNext() ) {
442                Group currGroup = (Group) it.next();
443                if ( !newGroupSet.contains( currGroup ) ) {
444                    checkForRight( RightType.GRANT, group );
445                }
446            }
447    
448            // check grant right for all groups requested to be added
449            it = newGroupSet.iterator();
450            while ( it.hasNext() ) {
451                Group currGroup = (Group) it.next();
452                if ( !oldGroupSet.contains( currGroup ) ) {
453                    checkForRight( RightType.GRANT, group );
454                }
455            }
456            registry.setGroupsForGroup( this, group, newGroups );
457        }
458    
459        /**
460         * Sets the <code>Groups</code> that a given <code>User</code> is a DIRECT member of.
461         *
462         * NOTE: Only performed if the acting user has the 'grant'-right for all the groups that are requested to be added /
463         * removed.
464         *
465         * @param user
466         * @param newGroups
467         * @throws GeneralSecurityException
468         * @throws UnauthorizedException
469         */
470        public void setGroupsForUser( User user, Group[] newGroups )
471                                throws GeneralSecurityException, UnauthorizedException {
472            SecurityAccessManager.getInstance().verify( this );
473            Group[] oldGroups = user.getGroups( this );
474    
475            // build set for old groups
476            HashSet<Group> oldGroupSet = new HashSet<Group>( oldGroups.length );
477            for ( int i = 0; i < oldGroups.length; i++ ) {
478                oldGroupSet.add( oldGroups[i] );
479            }
480            // build set for new groups
481            HashSet<Group> newGroupSet = new HashSet<Group>( oldGroups.length );
482            for ( int i = 0; i < newGroups.length; i++ ) {
483                newGroupSet.add( newGroups[i] );
484            }
485    
486            // check grant right for all groups requested to be removed
487            Iterator it = oldGroupSet.iterator();
488            while ( it.hasNext() ) {
489                Group group = (Group) it.next();
490                if ( !newGroupSet.contains( group ) ) {
491                    checkForRight( RightType.GRANT, group );
492                }
493            }
494    
495            // check grant right for all groups requested to be added
496            it = newGroupSet.iterator();
497            while ( it.hasNext() ) {
498                Group group = (Group) it.next();
499                if ( !oldGroupSet.contains( group ) ) {
500                    checkForRight( RightType.GRANT, group );
501                }
502            }
503            registry.setGroupsForUser( this, user, newGroups );
504        }
505    
506        /**
507         * Sets the members (groups) for a group.
508         *
509         * NOTE: Only performed if the acting user has the 'grant'-right on the group.
510         *
511         * @param group
512         * @param groups
513         * @throws GeneralSecurityException
514         * @throws UnauthorizedException
515         */
516        public void setGroupsInGroup( Group group, Group[] groups )
517                                throws GeneralSecurityException, UnauthorizedException {
518            SecurityAccessManager.getInstance().verify( this );
519            checkForRight( RightType.GRANT, group );
520            registry.setGroupsInGroup( this, group, groups );
521        }
522    
523        /**
524         * Sets the groups to be associated with the given role.
525         *
526         * NOTE: Only performed if the acting user has the 'grant'-right on the role.
527         *
528         * @param role
529         * @param groups
530         * @throws GeneralSecurityException
531         *             if not permitted
532         * @throws UnauthorizedException
533         */
534        public void setGroupsWithRole( Role role, Group[] groups )
535                                throws GeneralSecurityException, UnauthorizedException {
536            SecurityAccessManager.getInstance().verify( this );
537            checkForRight( RightType.GRANT, role );
538            registry.setGroupsWithRole( this, role, groups );
539        }
540    
541        /**
542         * Sets the privileges for a certain role.
543         *
544         * NOTE: Only performed if the acting user has all the privileges he is trying to grant.
545         *
546         * FIXME: Shouldn't that be "... to grant / withdraw"?
547         *
548         * @param role
549         * @param privileges
550         * @throws GeneralSecurityException
551         *             if not permitted
552         */
553        public void setPrivilegesForRole( Role role, Privilege[] privileges )
554                                throws GeneralSecurityException {
555            SecurityAccessManager.getInstance().verify( this );
556            Privilege[] holderPrivileges = user.getPrivileges( this );
557            HashSet<Privilege> holderSet = new HashSet<Privilege>( holderPrivileges.length );
558            for ( int i = 0; i < holderPrivileges.length; i++ ) {
559                holderSet.add( holderPrivileges[i] );
560            }
561            for ( int i = 0; i < privileges.length; i++ ) {
562                if ( !holderSet.contains( privileges[i] ) ) {
563                    throw new GeneralSecurityException( "The requested operation requires the privilege '"
564                                                        + privileges[i].getName() + "'." );
565                }
566            }
567            registry.setPrivilegesForRole( this, role, privileges );
568        }
569    
570        /**
571         * Sets the <code>Rights</code> that a certain role has on a given object.
572         *
573         * NOTE: Only performed if the acting user has the 'update'-right on the role and the 'grant'-right on the securable
574         * object.
575         *
576         * @param object
577         * @param role
578         * @param rights
579         * @throws GeneralSecurityException
580         *             if not permitted
581         * @throws UnauthorizedException
582         */
583        public void setRights( SecurableObject object, Role role, Right[] rights )
584                                throws GeneralSecurityException, UnauthorizedException {
585            SecurityAccessManager.getInstance().verify( this );
586            checkForRight( RightType.UPDATE, role );
587            checkForRight( RightType.GRANT, object );
588            registry.setRights( this, object, role, rights );
589        }
590    
591        /**
592         * Sets one certain right that a certain role has on the given objects.
593         *
594         * NOTE: Only performed if the acting user has the 'update'-right on the role and the 'grant'-right on the securable
595         * objects.
596         *
597         * @param objects
598         * @param role
599         * @param right
600         * @throws GeneralSecurityException
601         *             if not permitted
602         * @throws UnauthorizedException
603         */
604        public void setRights( SecurableObject[] objects, Role role, Right right )
605                                throws GeneralSecurityException, UnauthorizedException {
606            SecurityAccessManager.getInstance().verify( this );
607            checkForRight( RightType.UPDATE, role );
608            for ( int i = 0; i < objects.length; i++ ) {
609                checkForRight( RightType.GRANT, objects[i] );
610            }
611            registry.setRights( this, objects, role, right );
612        }
613    
614        /**
615         * Adds the specified <code>Rights</code> on the passed object to the passed role. If they are already present,
616         * nothing happens.
617         *
618         * @param object
619         * @param role
620         * @param additionalRights
621         * @throws GeneralSecurityException
622         * @throws UnauthorizedException
623         */
624        public void addRights( SecurableObject object, Role role, Right[] additionalRights )
625                                throws GeneralSecurityException, UnauthorizedException {
626            SecurityAccessManager.getInstance().verify( this );
627            checkForRight( RightType.UPDATE, role );
628            checkForRight( RightType.GRANT, object );
629            RightSet presentRights = new RightSet( registry.getRights( this, object, role ) );
630            RightSet newRights = presentRights.merge( new RightSet( additionalRights ) );
631            registry.setRights( this, object, role, newRights.toArray( object ) );
632        }
633    
634        /**
635         * Adds the specified <code>Rights</code> on the passed object to the passed role. If they are already present,
636         * nothing happens.
637         *
638         * @param object
639         * @param role
640         * @param types
641         * @throws UnauthorizedException
642         * @throws GeneralSecurityException
643         */
644        public void addRights( SecurableObject object, Role role, RightType[] types )
645                                throws UnauthorizedException, GeneralSecurityException {
646            Right[] additionalRights = new Right[types.length];
647            for ( int i = 0; i < additionalRights.length; i++ ) {
648                additionalRights[i] = new Right( object, types[i] );
649            }
650            addRights( object, role, additionalRights );
651        }
652    
653        /**
654         * Removes all rights of the specified types that the role may have on the given <code>SecurableObject</code>.
655         *
656         * @param object
657         * @param role
658         * @param types
659         * @throws GeneralSecurityException
660         * @throws UnauthorizedException
661         */
662        public void removeRights( SecurableObject object, Role role, RightType[] types )
663                                throws GeneralSecurityException, UnauthorizedException {
664            SecurityAccessManager.getInstance().verify( this );
665            checkForRight( RightType.UPDATE, role );
666            checkForRight( RightType.GRANT, object );
667    
668            Right[] rights = registry.getRights( this, object, role );
669            List<Right> newRightList = new ArrayList<Right>( 20 );
670            for ( int i = 0; i < rights.length; i++ ) {
671                RightType type = rights[i].getType();
672                boolean remove = true;
673                for ( int j = 0; j < types.length; j++ ) {
674                    if ( type.equals( types[j] ) ) {
675                        remove = true;
676                    }
677                }
678                if ( !remove ) {
679                    newRightList.add( rights[i] );
680                }
681            }
682            Right[] newRights = newRightList.toArray( new Right[newRightList.size()] );
683            registry.setRights( this, object, role, newRights );
684        }
685    
686        /**
687         * Sets the members (users) in a group.
688         *
689         * NOTE: Only performed if the acting user has the 'grant'-right on the group.
690         *
691         * @param group
692         * @param users
693         * @throws GeneralSecurityException
694         * @throws UnauthorizedException
695         */
696        public void setUsersInGroup( Group group, User[] users )
697                                throws GeneralSecurityException, UnauthorizedException {
698            SecurityAccessManager.getInstance().verify( this );
699            checkForRight( RightType.GRANT, group );
700            registry.setUsersInGroup( this, group, users );
701        }
702    
703        /**
704         * Sets the users to be associated with the given role (DIRECTLY, i.e. not via group memberships).
705         *
706         * NOTE: Only performed if the user has the 'grant'-right on the role.
707         *
708         * @param role
709         * @param users
710         * @throws GeneralSecurityException
711         *             if not permitted
712         * @throws UnauthorizedException
713         */
714        public void setUsersWithRole( Role role, User[] users )
715                                throws GeneralSecurityException, UnauthorizedException {
716            SecurityAccessManager.getInstance().verify( this );
717            checkForRight( RightType.GRANT, role );
718            registry.setUsersWithRole( this, role, users );
719        }
720    
721        @Override
722        public String toString() {
723            StringBuffer sb = new StringBuffer();
724            try {
725                User[] users = getAllUsers();
726    
727                sb.append( "\n\nSecurityAccess @ " + System.currentTimeMillis() );
728    
729                sb.append( "\n\n" ).append( users.length ).append( " registered users:\n" );
730                for ( int i = 0; i < users.length; i++ ) {
731                    sb.append( users[i].toString( this ) ).append( "\n" );
732                }
733                Group[] groups = getAllGroups();
734                sb.append( "\n" ).append( groups.length ).append( " registered groups:\n" );
735                for ( int i = 0; i < groups.length; i++ ) {
736                    sb.append( groups[i].toString( this ) ).append( "\n" );
737                }
738                Role[] roles = getAllRoles();
739                sb.append( "\n" ).append( roles.length ).append( " registered roles:\n" );
740                for ( int i = 0; i < roles.length; i++ ) {
741                    sb.append( roles[i].toString( this ) ).append( "\n" );
742                }
743            } catch ( Exception e ) {
744                e.printStackTrace();
745            }
746            return sb.toString();
747        }
748    
749        /**
750         * @param address
751         * @param title
752         * @param objects
753         * @param type
754         * @return the new service
755         * @throws GeneralSecurityException
756         */
757        public Service registerService( String address, String title, List<StringPair> objects, String type )
758                                throws GeneralSecurityException {
759            getInstance().verify( this );
760            checkForPrivilege( ADDOBJECT );
761            Service service = registry.registerService( this, address, title, objects, type );
762            return service;
763        }
764    
765        /**
766         * @param service
767         * @throws GeneralSecurityException
768         */
769        public void deregisterService( Service service )
770                                throws GeneralSecurityException {
771            getInstance().verify( this );
772            // it's probably not necessary to actually use the rights management for this
773            // checkForRight( DELETE, service );
774            registry.deregisterService( this, service );
775        }
776    
777        /**
778         * @param oldService
779         * @param newService
780         * @throws ReadWriteLockInvalidException
781         * @throws GeneralSecurityException
782         */
783        public void updateService( Service oldService, Service newService )
784                                throws ReadWriteLockInvalidException, GeneralSecurityException {
785            getInstance().verify( this );
786            registry.updateService( this, oldService, newService );
787        }
788    
789        /**
790         * @param service
791         * @param oldName
792         * @param newName
793         * @throws ReadWriteLockInvalidException
794         * @throws GeneralSecurityException
795         */
796        public void renameObject( Service service, String oldName, String newName )
797                                throws ReadWriteLockInvalidException, GeneralSecurityException {
798            getInstance().verify( this );
799            registry.renameObject( this, service, oldName, newName );
800        }
801    
802        /**
803         * @param service
804         * @param newTitle
805         * @param newAddress
806         * @throws GeneralSecurityException
807         */
808        public void editService( Service service, String newTitle, String newAddress )
809                                throws GeneralSecurityException {
810            getInstance().verify( this );
811            registry.editService( this, service, newTitle, newAddress );
812        }
813    
814        /**
815         *
816         */
817        void renew() {
818            this.timestamp = System.currentTimeMillis();
819        }
820    
821    }