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