View Javadoc

1   package org.apache.maven.continuum.management.redback;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.continuum.management.DataManagementException;
23  import org.apache.maven.continuum.management.DataManagementTool;
24  import org.codehaus.plexus.jdo.JdoFactory;
25  import org.codehaus.plexus.jdo.PlexusJdoUtils;
26  import org.codehaus.plexus.jdo.PlexusStoreException;
27  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.JdoOperation;
28  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.JdoPermission;
29  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.JdoResource;
30  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.JdoRole;
31  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.JdoUserAssignment;
32  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.RbacDatabase;
33  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.RbacJdoModelModelloMetadata;
34  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.io.stax.RbacJdoModelStaxReader;
35  import org.codehaus.plexus.security.authorization.rbac.jdo.v0_9_0.io.stax.RbacJdoModelStaxWriter;
36  import org.codehaus.plexus.security.keys.jdo.v0_9_0.AuthenticationKeyDatabase;
37  import org.codehaus.plexus.security.keys.jdo.v0_9_0.JdoAuthenticationKey;
38  import org.codehaus.plexus.security.keys.jdo.v0_9_0.PlexusSecurityKeyManagementJdoModelloMetadata;
39  import org.codehaus.plexus.security.keys.jdo.v0_9_0.io.stax.PlexusSecurityKeyManagementJdoStaxReader;
40  import org.codehaus.plexus.security.keys.jdo.v0_9_0.io.stax.PlexusSecurityKeyManagementJdoStaxWriter;
41  import org.codehaus.plexus.security.rbac.RBACObjectAssertions;
42  import org.codehaus.plexus.security.rbac.RbacManagerException;
43  import org.codehaus.plexus.security.user.Messages;
44  import org.codehaus.plexus.security.user.UserManagerException;
45  import org.codehaus.plexus.security.user.jdo.v0_9_0.JdoUser;
46  import org.codehaus.plexus.security.user.jdo.v0_9_0.UserDatabase;
47  import org.codehaus.plexus.security.user.jdo.v0_9_0.UserManagementModelloMetadata;
48  import org.codehaus.plexus.security.user.jdo.v0_9_0.io.stax.UserManagementStaxReader;
49  import org.codehaus.plexus.security.user.jdo.v0_9_0.io.stax.UserManagementStaxWriter;
50  import org.codehaus.plexus.util.IOUtil;
51  import org.codehaus.plexus.util.StringUtils;
52  
53  import javax.jdo.JDOHelper;
54  import javax.jdo.PersistenceManager;
55  import javax.xml.stream.XMLStreamException;
56  import java.io.File;
57  import java.io.FileReader;
58  import java.io.FileWriter;
59  import java.io.IOException;
60  import java.util.ArrayList;
61  import java.util.HashMap;
62  import java.util.Iterator;
63  import java.util.List;
64  import java.util.Map;
65  
66  /**
67   * JDO implementation the database management tool API.
68   * @version $Id: LegacyJdoDataManagementTool.java 785095 2009-06-16 07:20:12Z ctan $
69   * @plexus.component role="org.apache.maven.continuum.management.DataManagementTool" role-hint="legacy-redback-jdo"
70   */
71  public class LegacyJdoDataManagementTool
72      implements DataManagementTool
73  {
74      private static final String USERS_XML_NAME = "users.xml";
75  
76      private static final String KEYS_XML_NAME = "keys.xml";
77  
78      private static final String RBAC_XML_NAME = "rbac.xml";
79  
80      /**
81       * @plexus.requirement role-hint="users"
82       */
83      private JdoFactory jdoFactory;
84  
85      public void backupDatabase( File backupDirectory )
86          throws IOException
87      {
88          try
89          {
90              backupKeyDatabase( backupDirectory );
91              backupRBACDatabase( backupDirectory );
92              backupUserDatabase( backupDirectory );
93          }
94          catch ( XMLStreamException e )
95          {
96              throw new DataManagementException( e );
97          }
98          catch ( RbacManagerException e )
99          {
100             throw new DataManagementException( e );
101         }
102     }
103 
104     public void restoreDatabase( File backupDirectory, boolean strict )
105         throws IOException, DataManagementException
106     {
107         try
108         {
109             restoreKeysDatabase( backupDirectory );
110             restoreRBACDatabase( backupDirectory );
111             restoreUsersDatabase( backupDirectory );
112         }
113         catch ( XMLStreamException e )
114         {
115             throw new DataManagementException( e );
116         }
117         catch ( PlexusStoreException e )
118         {
119             throw new DataManagementException( e );
120         }
121         catch ( RbacManagerException e )
122         {
123             throw new DataManagementException( e );
124         }
125     }
126 
127     public void eraseDatabase()
128     {
129         eraseKeysDatabase();
130         eraseRBACDatabase();
131         eraseUsersDatabase();
132     }
133 
134     public void backupRBACDatabase( File backupDirectory )
135         throws RbacManagerException, IOException, XMLStreamException
136     {
137         RbacDatabase database = new RbacDatabase();
138         database.setRoles( PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoRole.class ) );
139         database.setUserAssignments(
140             PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoUserAssignment.class ) );
141         database.setPermissions( PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoPermission.class ) );
142         database.setOperations( PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoOperation.class ) );
143         database.setResources( PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoResource.class ) );
144 
145         RbacJdoModelStaxWriter writer = new RbacJdoModelStaxWriter();
146         FileWriter fileWriter = new FileWriter( new File( backupDirectory, RBAC_XML_NAME ) );
147         try
148         {
149             writer.write( fileWriter, database );
150         }
151         finally
152         {
153             IOUtil.close( fileWriter );
154         }
155     }
156 
157     public void backupUserDatabase( File backupDirectory )
158         throws IOException, XMLStreamException
159     {
160         UserDatabase database = new UserDatabase();
161         database.setUsers( PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoUser.class ) );
162 
163         UserManagementStaxWriter writer = new UserManagementStaxWriter();
164         FileWriter fileWriter = new FileWriter( new File( backupDirectory, USERS_XML_NAME ) );
165         try
166         {
167             writer.write( fileWriter, database );
168         }
169         finally
170         {
171             IOUtil.close( fileWriter );
172         }
173     }
174 
175     public void backupKeyDatabase( File backupDirectory )
176         throws IOException, XMLStreamException
177     {
178         AuthenticationKeyDatabase database = new AuthenticationKeyDatabase();
179         List keys = PlexusJdoUtils.getAllObjectsDetached( getPersistenceManager(), JdoAuthenticationKey.class );
180 
181         database.setKeys( keys );
182 
183         PlexusSecurityKeyManagementJdoStaxWriter writer = new PlexusSecurityKeyManagementJdoStaxWriter();
184         FileWriter fileWriter = new FileWriter( new File( backupDirectory, KEYS_XML_NAME ) );
185         try
186         {
187             writer.write( fileWriter, database );
188         }
189         finally
190         {
191             IOUtil.close( fileWriter );
192         }
193     }
194 
195     private PersistenceManager getPersistenceManager()
196     {
197         PersistenceManager pm = jdoFactory.getPersistenceManagerFactory().getPersistenceManager();
198 
199         pm.getFetchPlan().setMaxFetchDepth( 5 );
200 
201         return pm;
202     }
203 
204     public void restoreRBACDatabase( File backupDirectory )
205         throws IOException, XMLStreamException, RbacManagerException, PlexusStoreException
206     {
207         RbacJdoModelStaxReader reader = new RbacJdoModelStaxReader();
208 
209         FileReader fileReader = new FileReader( new File( backupDirectory, RBAC_XML_NAME ) );
210 
211         RbacDatabase database;
212         try
213         {
214             database = reader.read( fileReader );
215         }
216         finally
217         {
218             IOUtil.close( fileReader );
219         }
220 
221         Map<String, JdoPermission> permissionMap = new HashMap<String, JdoPermission>();
222         Map<String, JdoResource> resources = new HashMap<String, JdoResource>();
223         Map<String, JdoOperation> operations = new HashMap<String, JdoOperation>();
224         for ( Iterator i = database.getRoles().iterator(); i.hasNext(); )
225         {
226             JdoRole role = (JdoRole) i.next();
227 
228             // TODO: this could be generally useful and put into saveRole itself as long as the performance penalty isn't too harsh.
229             //   Currently it always saves everything where it could pull pack the existing permissions, etc if they exist
230             List<JdoPermission> permissions = new ArrayList<JdoPermission>();
231             for ( Iterator j = role.getPermissions().iterator(); j.hasNext(); )
232             {
233                 JdoPermission permission = (JdoPermission) j.next();
234 
235                 if ( permissionMap.containsKey( permission.getName() ) )
236                 {
237                     permission = permissionMap.get( permission.getName() );
238                 }
239                 else if ( objectExists( permission ) )
240                 {
241                     permission = (JdoPermission) PlexusJdoUtils.getObjectById( getPersistenceManager(),
242                                                                                JdoPermission.class,
243                                                                                permission.getName() );
244                     permissionMap.put( permission.getName(), permission );
245                 }
246                 else
247                 {
248                     JdoOperation operation = (JdoOperation) permission.getOperation();
249                     if ( operations.containsKey( operation.getName() ) )
250                     {
251                         operation = operations.get( operation.getName() );
252                     }
253                     else if ( objectExists( operation ) )
254                     {
255                         operation = (JdoOperation) PlexusJdoUtils.getObjectById( getPersistenceManager(),
256                                                                                  JdoOperation.class,
257                                                                                  operation.getName() );
258                         operations.put( operation.getName(), operation );
259                     }
260                     else
261                     {
262                         RBACObjectAssertions.assertValid( operation );
263                         operation =
264                             (JdoOperation) PlexusJdoUtils.saveObject( getPersistenceManager(), operation, null );
265                         operations.put( operation.getName(), operation );
266                     }
267                     permission.setOperation( operation );
268 
269                     JdoResource resource = (JdoResource) permission.getResource();
270                     if ( resources.containsKey( resource.getIdentifier() ) )
271                     {
272                         resource = resources.get( resource.getIdentifier() );
273                     }
274                     else if ( objectExists( resource ) )
275                     {
276                         resource = (JdoResource) PlexusJdoUtils.getObjectById( getPersistenceManager(),
277                                                                                JdoResource.class,
278                                                                                resource.getIdentifier() );
279                         resources.put( resource.getIdentifier(), resource );
280                     }
281                     else
282                     {
283                         RBACObjectAssertions.assertValid( resource );
284                         resource = (JdoResource) PlexusJdoUtils.saveObject( getPersistenceManager(), resource, null );
285                         resources.put( resource.getIdentifier(), resource );
286                     }
287                     permission.setResource( resource );
288 
289                     RBACObjectAssertions.assertValid( permission );
290                     permission = (JdoPermission) PlexusJdoUtils.saveObject( getPersistenceManager(), permission, null );
291                     permissionMap.put( permission.getName(), permission );
292                 }
293                 permissions.add( permission );
294             }
295             role.setPermissions( permissions );
296 
297             RBACObjectAssertions.assertValid( role );
298 
299             PlexusJdoUtils.saveObject( getPersistenceManager(), role, new String[]{null} );
300         }
301 
302         for ( Iterator i = database.getUserAssignments().iterator(); i.hasNext(); )
303         {
304             JdoUserAssignment userAssignment = (JdoUserAssignment) i.next();
305 
306             RBACObjectAssertions.assertValid( "Save User Assignment", userAssignment );
307 
308             PlexusJdoUtils.saveObject( getPersistenceManager(), userAssignment, new String[]{null} );
309         }
310     }
311 
312     private boolean objectExists( Object object )
313     {
314         return JDOHelper.getObjectId( object ) != null;
315     }
316 
317     public void restoreUsersDatabase( File backupDirectory )
318         throws IOException, XMLStreamException
319     {
320         UserManagementStaxReader reader = new UserManagementStaxReader();
321 
322         FileReader fileReader = new FileReader( new File( backupDirectory, USERS_XML_NAME ) );
323 
324         UserDatabase database;
325         try
326         {
327             database = reader.read( fileReader );
328         }
329         finally
330         {
331             IOUtil.close( fileReader );
332         }
333 
334         for ( Iterator i = database.getUsers().iterator(); i.hasNext(); )
335         {
336             JdoUser user = (JdoUser) i.next();
337 
338             if ( !( user instanceof JdoUser ) )
339             {
340                 throw new UserManagerException( "Unable to Add User. User object " + user.getClass().getName() +
341                     " is not an instance of " + JdoUser.class.getName() );
342             }
343 
344             if ( StringUtils.isEmpty( user.getUsername() ) )
345             {
346                 throw new IllegalStateException(
347                     Messages.getString( "user.manager.cannot.add.user.without.username" ) ); //$NON-NLS-1$
348             }
349 
350             PlexusJdoUtils.addObject( getPersistenceManager(), user );
351 
352         }
353     }
354 
355     public void restoreKeysDatabase( File backupDirectory )
356         throws IOException, XMLStreamException
357     {
358         PlexusSecurityKeyManagementJdoStaxReader reader = new PlexusSecurityKeyManagementJdoStaxReader();
359 
360         FileReader fileReader = new FileReader( new File( backupDirectory, KEYS_XML_NAME ) );
361 
362         AuthenticationKeyDatabase database;
363         try
364         {
365             database = reader.read( fileReader );
366         }
367         finally
368         {
369             IOUtil.close( fileReader );
370         }
371 
372         for ( Iterator i = database.getKeys().iterator(); i.hasNext(); )
373         {
374             JdoAuthenticationKey key = (JdoAuthenticationKey) i.next();
375 
376             PlexusJdoUtils.addObject( getPersistenceManager(), key );
377         }
378     }
379 
380     public void eraseRBACDatabase()
381     {
382         // Must delete in order so that FK constraints don't get violated
383         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoRole.class );
384         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoPermission.class );
385         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoOperation.class );
386         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoResource.class );
387         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoUserAssignment.class );
388         PlexusJdoUtils.removeAll( getPersistenceManager(), RbacJdoModelModelloMetadata.class );
389     }
390 
391     public void eraseUsersDatabase()
392     {
393         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoUser.class );
394         PlexusJdoUtils.removeAll( getPersistenceManager(), UserManagementModelloMetadata.class );
395     }
396 
397     public void eraseKeysDatabase()
398     {
399         PlexusJdoUtils.removeAll( getPersistenceManager(), JdoAuthenticationKey.class );
400         PlexusJdoUtils.removeAll( getPersistenceManager(), PlexusSecurityKeyManagementJdoModelloMetadata.class );
401     }
402 }