    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/portal/standard/security/control/StoreGroupsListener.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.portal.standard.security.control;
    037
    038    import java.util.ArrayList;
    039
    040    import org.deegree.enterprise.control.AbstractListener;
    041    import org.deegree.enterprise.control.FormEvent;
    042    import org.deegree.enterprise.control.RPCException;
    043    import org.deegree.enterprise.control.RPCMember;
    044    import org.deegree.enterprise.control.RPCMethodCall;
    045    import org.deegree.enterprise.control.RPCParameter;
    046    import org.deegree.enterprise.control.RPCStruct;
    047    import org.deegree.enterprise.control.RPCWebEvent;
    048    import org.deegree.framework.log.ILogger;
    049    import org.deegree.framework.log.LoggerFactory;
    050    import org.deegree.i18n.Messages;
    051    import org.deegree.security.GeneralSecurityException;
    052    import org.deegree.security.UnauthorizedException;
    053    import org.deegree.security.drm.SecurityAccessManager;
    054    import org.deegree.security.drm.SecurityTransaction;
    055    import org.deegree.security.drm.model.Group;
    056    import org.deegree.security.drm.model.User;
    057
    058    /**
    059     * This <code>Listener</code> reacts on RPC-StoreGroups events, extracts the contained user/group
    060     * relations and updates the <code>SecurityManager</code> accordingly.
    061     *
    062     * Access constraints:
    063     * <ul>
    064     * <li>only users that have the 'SEC_ADMIN'-role are allowed</li>
    065     * </ul>
    066     *
    067     * @author <a href="mschneider@lat-lon.de">Markus Schneider </a>
    068     * @author last edited by: $Author: mschneider $
    069     *
    070     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    071     */
    072    public class StoreGroupsListener extends AbstractListener {
    073
    074        private static final ILogger LOG = LoggerFactory.getLogger( StoreGroupsListener.class );
    075
    076        @Override
    077        public void actionPerformed( FormEvent event ) {
    078
    079            SecurityAccessManager manager = null;
    080            SecurityTransaction transaction = null;
    081
    082            try {
    083                RPCWebEvent ev = (RPCWebEvent) event;
    084                RPCMethodCall rpcCall = ev.getRPCMethodCall();
    085                RPCParameter[] params = rpcCall.getParameters();
    086
    087                // values are Integers (groupIds) or Strings (groupNames)
    088                Object[] groups = new Object[params.length];
    089                // values of the ArrayLists are Integers (groupIds)
    090                ArrayList[] userMembersIds = new ArrayList[params.length];
    091                // values of the ArrayLists are Integers (userIds)
    092                ArrayList[] groupMembersIds = new ArrayList[params.length];
    093
    094                for ( int i = 0; i < params.length; i++ ) {
    095                    ArrayList<Integer> userMemberList = new ArrayList<Integer>( 200 );
    096                    ArrayList<Integer> groupMemberList = new ArrayList<Integer>( 200 );
    097                    userMembersIds[i] = userMemberList;
    098                    groupMembersIds[i] = groupMemberList;
    099                    if ( !( params[0].getValue() instanceof RPCStruct ) ) {
    100                        throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_STRUCT" ) );
    101                    }
    102                    RPCStruct struct = (RPCStruct) params[i].getValue();
    103
    104                    // extract group-id / group-name
    105                    extractGroupInfo( groups, i, struct );
    106
    107                    // extract user members
    108                    extractUsers( userMemberList, struct );
    109
    110                    // extract group members
    111                    extractGroups( groupMemberList, struct );
    112
    113                }
    114
    115                // get Transaction and perform access check
    116                manager = SecurityAccessManager.getInstance();
    117                transaction = SecurityHelper.acquireTransaction( this );
    118                SecurityHelper.checkForAdminRole( transaction );
    119
    120                // remove deleted groups
    121                removeDeletedGroups( transaction, groups );
    122
    123                // save all submitted groups (and their members)
    124                saveSubmittedGroups( transaction, groups, userMembersIds, groupMembersIds );
    125                Group[] cycle = transaction.findGroupCycle();
    126                manager.commitTransaction( transaction );
    127                transaction = null;
    128
    129                StringBuffer sb = new StringBuffer( 200 );
    130                sb.append( Messages.getMessage( "IGEO_STD_SEC_SUCCESS_STOREGROUPS" ) );
    131
    132                if ( cycle != null ) {
    133                    sb.append( "<br><p><h4>" );
    134                    sb.append( Messages.getMessage( "IGEO_STD_SEC_SUCCESS_STOREGROUPS_ADDTXT" ) );
    135                    sb.append( "<br><code>" );
    136                    for ( int i = 0; i < cycle.length; i++ ) {
    137                        sb.append( cycle[i].getName() );
    138                        if ( i != cycle.length - 1 ) {
    139                            sb.append( " -> " );
    140                        }
    141                    }
    142                    sb.append( "</code></h4></p>" );
    143                }
    144
    145                getRequest().setAttribute( "MESSAGE", sb.toString() );
    146            } catch ( RPCException e ) {
    147                getRequest().setAttribute( "SOURCE", this.getClass().getName() );
    148                getRequest().setAttribute( "MESSAGE",
    149                                           Messages.getMessage( "IGEO_STD_SEC_ERROR_CHANGE_REQ",
    150                                                                e.getMessage() ) );
    151                setNextPage( "error.jsp" );
    152                LOG.logDebug( e.getMessage(), e );
    153
    154            } catch ( GeneralSecurityException e ) {
    155                getRequest().setAttribute( "SOURCE", this.getClass().getName() );
    156                getRequest().setAttribute( "MESSAGE",
    157                                           Messages.getMessage( "IGEO_STD_SEC_ERROR_CHANGE",
    158                                                                e.getMessage() ) );
    159                setNextPage( "error.jsp" );
    160                LOG.logDebug( e.getMessage(), e );
    161            } finally {
    162                if ( manager != null && transaction != null ) {
    163                    try {
    164                        manager.abortTransaction( transaction );
    165                    } catch ( GeneralSecurityException ex ) {
    166                        LOG.logDebug( ex.getMessage(), ex );
    167                    }
    168                }
    169            }
    170        }
    171
    172        private void saveSubmittedGroups( SecurityTransaction transaction, Object[] groups,
    173                                         ArrayList[] userMembersIds, ArrayList[] groupMembersIds )
    174                                throws GeneralSecurityException, UnauthorizedException {
    175            for ( int i = 0; i < groups.length; i++ ) {
    176                Group group;
    177                if ( groups[i] instanceof Integer ) {
    178                    group = transaction.getGroupById( ( (Integer) groups[i] ).intValue() );
    179                } else {
    180                    group = transaction.registerGroup( (String) groups[i], (String) groups[i] );
    181                }
    182
    183                // set user members
    184                User[] userMembers = new User[userMembersIds[i].size()];
    185                for ( int j = 0; j < userMembersIds[i].size(); j++ ) {
    186                    int userId = ( (Integer) userMembersIds[i].get( j ) ).intValue();
    187                    userMembers[j] = transaction.getUserById( userId );
    188                }
    189                transaction.setUsersInGroup( group, userMembers );
    190
    191                // set group members
    192                Group[] groupMembers = new Group[groupMembersIds[i].size()];
    193                for ( int j = 0; j < groupMembersIds[i].size(); j++ ) {
    194                    int groupId = ( (Integer) groupMembersIds[i].get( j ) ).intValue();
    195                    groupMembers[j] = transaction.getGroupById( groupId );
    196                }
    197                transaction.setGroupsInGroup( group, groupMembers );
    198            }
    199        }
    200
    201        private void removeDeletedGroups( SecurityTransaction transaction, Object[] groups )
    202                                throws GeneralSecurityException, UnauthorizedException {
    203            Group[] oldGroups = transaction.getAllGroups();
    204            for ( int i = 0; i < oldGroups.length; i++ ) {
    205                if ( oldGroups[i].getID() != Group.ID_SEC_ADMIN ) {
    206                    boolean deleted = true;
    207                    for ( int j = 0; j < groups.length; j++ ) {
    208                        if ( groups[j] instanceof Integer ) {
    209                            if ( ( (Integer) groups[j] ).intValue() == oldGroups[i].getID() ) {
    210                                deleted = false;
    211                            }
    212                        }
    213                    }
    214                    if ( deleted ) {
    215                        transaction.deregisterGroup( oldGroups[i] );
    216                    }
    217                }
    218            }
    219        }
    220
    221        private void extractGroups( ArrayList<Integer> groupMemberList, RPCStruct struct )
    222                                throws RPCException {
    223            RPCMember groupMembers = struct.getMember( "groupMembers" );
    224            if ( !( groupMembers.getValue() instanceof RPCParameter[] ) ) {
    225                throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY",
    226                                                             "groupMembers" ) );
    227            }
    228            RPCParameter[] memberArray = (RPCParameter[]) groupMembers.getValue();
    229            for ( int j = 0; j < memberArray.length; j++ ) {
    230                if ( !( memberArray[j].getValue() instanceof String ) ) {
    231                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY_VALUES",
    232                                                                 "groupMembers", "String" ) );
    233                }
    234                try {
    235                    groupMemberList.add( new Integer( (String) memberArray[j].getValue() ) );
    236                } catch ( NumberFormatException e ) {
    237                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_INVALID_ARRAY_VALUES",
    238                                                                 "groupMembers", "Integer" ) );
    239                }
    240            }
    241        }
    242
    243        private void extractUsers( ArrayList<Integer> userMemberList, RPCStruct struct )
    244                                throws RPCException {
    245            RPCMember userMembers = struct.getMember( "userMembers" );
    246            if ( !( userMembers.getValue() instanceof RPCParameter[] ) ) {
    247                throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY",
    248                                                             "userMembers" ) );
    249            }
    250            RPCParameter[] memberArray = (RPCParameter[]) userMembers.getValue();
    251            for ( int j = 0; j < memberArray.length; j++ ) {
    252                if ( !( memberArray[j].getValue() instanceof String ) ) {
    253                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_ARRAY_VALUES",
    254                                                                 "userMembers", "String" ) );
    255                }
    256                try {
    257                    userMemberList.add( new Integer( (String) memberArray[j].getValue() ) );
    258                } catch ( NumberFormatException e ) {
    259                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_INVALID_ARRAY_VALUES",
    260                                                                 "userMembers", "Integer" ) );
    261                }
    262            }
    263        }
    264
    265        private void extractGroupInfo( Object[] groups, int index, RPCStruct struct )
    266                                throws RPCException {
    267
    268            RPCMember groupId = struct.getMember( "groupId" );
    269            RPCMember groupName = struct.getMember( "groupName" );
    270            if ( ( groupId == null && groupName == null ) || ( groupId != null && groupName != null ) ) {
    271                throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUPS" ) );
    272            }
    273            if ( groupId != null ) {
    274                if ( !( groupId.getValue() instanceof String ) ) {
    275                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUP_PARAM",
    276                                                                 "groupId", "String" ) );
    277                }
    278                try {
    279                    groups[index] = ( new Integer( (String) groupId.getValue() ) );
    280                } catch ( NumberFormatException e ) {
    281                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUP_PARAM",
    282                                                                 "groupId", "Integer" ) );
    283                }
    284            } else {
    285                if ( !( groupName.getValue() instanceof String ) ) {
    286                    throw new RPCException( Messages.getMessage( "IGEO_STD_SEC_MISSING_GROUP_PARAM",
    287                                                                 "groupName", "String" ) );
    288                }
    289
    290                groups[index] = groupName.getValue();
    291            }
    292        }
    293    }