001    /*
002     * 
003     * $Revision: 15270 $ $Date: 2009-05-25 17:27:57 +0200 (Mon, 25 May 2009) $
004     *
005     * This file is part of ***  M y C o R e  ***
006     * See http://www.mycore.de/ for details.
007     *
008     * This program is free software; you can use it, redistribute it
009     * and / or modify it under the terms of the GNU General Public License
010     * (GPL) as published by the Free Software Foundation; either version 2
011     * of the License or (at your option) any later version.
012     *
013     * This program is distributed in the hope that it will be useful, but
014     * WITHOUT ANY WARRANTY; without even the implied warranty of
015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016     * GNU General Public License for more details.
017     *
018     * You should have received a copy of the GNU General Public License
019     * along with this program, in a file called gpl.txt or license.txt.
020     * If not, write to the Free Software Foundation Inc.,
021     * 59 Temple Place - Suite 330, Boston, MA  02111-1307 USA
022     */
023    
024    package org.mycore.frontend.cli;
025    
026    import static org.mycore.common.MCRConstants.DEFAULT_ENCODING;
027    
028    import java.io.File;
029    import java.io.FileOutputStream;
030    import java.util.ArrayList;
031    import java.util.List;
032    
033    import org.apache.log4j.Logger;
034    import org.jdom.Document;
035    import org.jdom.Element;
036    import org.jdom.output.Format;
037    import org.jdom.output.XMLOutputter;
038    
039    import org.mycore.common.MCRException;
040    import org.mycore.common.MCRSessionMgr;
041    import org.mycore.common.xml.MCRXMLHelper;
042    import org.mycore.user.MCRCrypt;
043    import org.mycore.user.MCRGroup;
044    import org.mycore.user.MCRUser;
045    import org.mycore.user.MCRUserMgr;
046    
047    /**
048     * This class provides a set of commands for the org.mycore.user management
049     * which can be used by the command line interface.
050     * 
051     * @author Detlev Degenhardt
052     * @author Frank L\u00fctzenkirchen
053     * @author Jens Kupferschmidt
054     * @version $Revision: 15270 $ $Date: 2007-12-19 17:31:52 +0100 (Mi, 19 Dez
055     *          2007) $
056     */
057    public class MCRUserCommands extends MCRAbstractCommands {
058        /** The logger */
059        private static Logger LOGGER = Logger.getLogger(MCRUserCommands.class.getName());
060    
061        /**
062         * The constructor.
063         */
064        public MCRUserCommands() {
065            super();
066    
067            MCRCommand com = null;
068    
069            com = new MCRCommand("init superuser", "org.mycore.frontend.cli.MCRUserCommands.initSuperuser",
070                    "Initialized the user system. This command runs only if the user database does not exist.");
071            command.add(com);
072    
073            com = new MCRCommand("check user data consistency", "org.mycore.frontend.cli.MCRUserCommands.checkConsistency",
074                    "This command checks the user system for its consistency.");
075            command.add(com);
076    
077            com = new MCRCommand("encrypt passwords in user xml file {0} to file {1}",
078                    "org.mycore.frontend.cli.MCRUserCommands.encryptPasswordsInXMLFile String String",
079                    "This is a migration tool to change old plain text password entries to encrpted entries.");
080            command.add(com);
081    
082            com = new MCRCommand("set password for user {0} to {1}", "org.mycore.frontend.cli.MCRUserCommands.setPassword String String",
083                    "This command sets a new password for the user. You must be this user or you must have administrator access.");
084            command.add(com);
085    
086            com = new MCRCommand("set user management to ro mode", "org.mycore.frontend.cli.MCRUserCommands.setLock",
087                    "The command changes the management mode of the user system to read-only.");
088            command.add(com);
089    
090            com = new MCRCommand("set user management to rw mode", "org.mycore.frontend.cli.MCRUserCommands.setunLock",
091                    "The command changes the management mode of the user system to read-write.");
092            command.add(com);
093    
094            com = new MCRCommand("enable user {0}", "org.mycore.frontend.cli.MCRUserCommands.enableUser String",
095                    "The command enables the user for the access.");
096            command.add(com);
097    
098            com = new MCRCommand("disable user {0}", "org.mycore.frontend.cli.MCRUserCommands.disableUser String",
099                    "The command disables the user from the access.");
100            command.add(com);
101    
102            com = new MCRCommand("create group data from file {0}", "org.mycore.frontend.cli.MCRUserCommands.createGroupFromFile String",
103                    "The command creates one or more new groups in the user system with data from the file {0}. This create makes a constency check.");
104            command.add(com);
105    
106            com = new MCRCommand(
107                    "import user system from files {0} {1}",
108                    "org.mycore.frontend.cli.MCRUserCommands.importUserSystemFromFiles String String",
109                    "The command imports the user system with data from the group file {0} and the user file {1}. The command is designd only for recovery processes.");
110            command.add(com);
111    
112            com = new MCRCommand("delete group {0}", "org.mycore.frontend.cli.MCRUserCommands.deleteGroup String",
113                    "The command delete the group {0} from the user system, but only if it has no user members.");
114            command.add(com);
115    
116            com = new MCRCommand("create user data from file {0}", "org.mycore.frontend.cli.MCRUserCommands.createUserFromFile String",
117                    "The command create one or more new users in the user system with data from the file {0}.");
118            command.add(com);
119    
120            com = new MCRCommand("update user data from file {0}", "org.mycore.frontend.cli.MCRUserCommands.updateUserFromFile String",
121                    "The command update one or more users in the user system with data from the file {0}.");
122            command.add(com);
123    
124            com = new MCRCommand("delete user {0}", "org.mycore.frontend.cli.MCRUserCommands.deleteUser String",
125                    "The command delete the user {0}.");
126            command.add(com);
127    
128            com = new MCRCommand("add user {0} as member to group {1}",
129                    "org.mycore.frontend.cli.MCRUserCommands.addMemberUserToGroup String String",
130                    "The command add a user {0} as secondary member in the group {1}.");
131            command.add(com);
132    
133            com = new MCRCommand("remove user {0} as member from group {1}",
134                    "org.mycore.frontend.cli.MCRUserCommands.removeMemberUserFromGroup String String",
135                    "The command remove the user {0} as secondary member from the group {1}.");
136            command.add(com);
137    
138            com = new MCRCommand("list all groups", "org.mycore.frontend.cli.MCRUserCommands.listAllGroups", "The command list all groups.");
139            command.add(com);
140    
141            com = new MCRCommand("list group {0}", "org.mycore.frontend.cli.MCRUserCommands.listGroup String",
142                    "The command list the group {0}.");
143            command.add(com);
144    
145            com = new MCRCommand("list all users", "org.mycore.frontend.cli.MCRUserCommands.listAllUsers", "The command list all users.");
146            command.add(com);
147    
148            com = new MCRCommand("list user {0}", "org.mycore.frontend.cli.MCRUserCommands.listUser String", "The command list the user {0}.");
149            command.add(com);
150    
151            com = new MCRCommand("export all groups to file {0}", "org.mycore.frontend.cli.MCRUserCommands.exportAllGroupsToFile String",
152                    "The command exports all group data to the file {0}.");
153            command.add(com);
154    
155            com = new MCRCommand("export group {0} to file {1}", "org.mycore.frontend.cli.MCRUserCommands.exportGroupToFile String String",
156                    "The command exports the data of group {0} to the file {1}.");
157            command.add(com);
158    
159            com = new MCRCommand("export all users to file {0}", "org.mycore.frontend.cli.MCRUserCommands.exportAllUsersToFile String",
160                    "The command exports all user data to the file {0}.");
161            command.add(com);
162    
163            com = new MCRCommand("export user {0} to file {1}", "org.mycore.frontend.cli.MCRUserCommands.exportUserToFile String String",
164                    "The command exports the data of user {0} to the file {1}.");
165            command.add(com);
166        }
167    
168        /**
169         * This method initializes the user and group system an creates a superuser
170         * with values set in mycore.properties.private As 'super' default, if no
171         * properties were set, mcradmin with password mycore will be used.
172         */
173        public static void initSuperuser() throws MCRException {
174            String suser = CONFIG.getString("MCR.Users.Superuser.UserName", "administrator");
175            String spasswd = CONFIG.getString("MCR.Users.Superuser.UserPasswd", "alleswirdgut");
176            String sgroup = CONFIG.getString("MCR.Users.Superuser.GroupName", "admingroup");
177            String guser = CONFIG.getString("MCR.Users.Guestuser.UserName", "guest");
178            String gpasswd = CONFIG.getString("MCR.Users.Guestuser.UserPasswd", "guest");
179            String ggroup = CONFIG.getString("MCR.Users.Guestuser.GroupName", "guestgroup");
180    
181            // If CONFIGuration parameter defines that we use password encryption:
182            // encrypt!
183            String useCrypt = CONFIG.getString("MCR.Users.UsePasswordEncryption", "false");
184            boolean useEncryption = (useCrypt.trim().equals("true")) ? true : false;
185    
186            if (useEncryption) {
187                String cryptPwd = MCRCrypt.crypt(spasswd);
188                spasswd = cryptPwd;
189                cryptPwd = MCRCrypt.crypt(gpasswd);
190                gpasswd = cryptPwd;
191            }
192    
193            MCRSessionMgr.getCurrentSession().setCurrentUserID(suser);
194    
195            if (MCRUserMgr.instance().retrieveUser(suser) != null) {
196                if (MCRUserMgr.instance().retrieveGroup(sgroup) != null) {
197                    LOGGER.error("The superuser already exists!");
198                    return;
199                }
200            }
201    
202            // the superuser group
203            try {
204                ArrayList<String> admUserIDs = new ArrayList<String>();
205    
206                ArrayList<String> admGroupIDs = new ArrayList<String>();
207                ArrayList<String> mbrUserIDs = new ArrayList<String>();
208    
209                MCRGroup g = new MCRGroup(sgroup, suser, null, null, "The superuser group", admUserIDs, admGroupIDs, mbrUserIDs);
210    
211                MCRUserMgr.instance().initializeGroup(g, suser);
212            } catch (Exception e) {
213                throw new MCRException("Can't create the superuser group.", e);
214            }
215    
216            LOGGER.info("The group " + sgroup + " is installed.");
217    
218            // the superuser
219            try {
220                ArrayList<String> groupIDs = new ArrayList<String>();
221                groupIDs.add(sgroup);
222    
223                MCRUser u = new MCRUser(1, suser, suser, null, null, true, true, "Superuser", spasswd, sgroup, groupIDs, null, null, null,
224                        null, null, null, null, null, null, null, null, null, null, null, null, null);
225    
226                MCRUserMgr.instance().initializeUser(u, suser);
227            } catch (Exception e) {
228                throw new MCRException("Can't create the superuser.", e);
229            }
230    
231            LOGGER.info("The user " + suser + " with password " + CONFIG.getString("MCR.Users.Superuser.UserPasswd", "alleswirdgut")
232                    + " is installed.");
233    
234            // the guest group
235            try {
236                ArrayList<String> admUserIDs = new ArrayList<String>();
237                admUserIDs.add(suser);
238    
239                ArrayList<String> admGroupIDs = new ArrayList<String>();
240                admGroupIDs.add(sgroup);
241    
242                ArrayList<String> mbrUserIDs = new ArrayList<String>();
243                mbrUserIDs.add(suser);
244    
245                MCRGroup g = new MCRGroup(ggroup, suser, null, null, "The guest group", admUserIDs, admGroupIDs, mbrUserIDs);
246    
247                MCRUserMgr.instance().initializeGroup(g, suser);
248            } catch (Exception e) {
249                throw new MCRException("Can't create the guest group.", e);
250            }
251    
252            LOGGER.info("The group " + ggroup + " is installed.");
253    
254            // the guest
255            try {
256                ArrayList<String> groupIDs = new ArrayList<String>();
257                groupIDs.add(ggroup);
258    
259                MCRUser u = new MCRUser(2, guser, suser, null, null, true, true, "gast", gpasswd, ggroup, groupIDs, null, null, null, null,
260                        null, null, null, null, null, null, null, null, null, null, null, null);
261    
262                MCRUserMgr.instance().initializeUser(u, suser);
263            } catch (Exception e) {
264                throw new MCRException("Can't create the guest user.", e);
265            }
266    
267            LOGGER.info("The user " + guser + " with password " + CONFIG.getString("CR.Users.Guestuser.UserPasswd", "gast") + " is installed.");
268    
269            MCRSessionMgr.getCurrentSession().setCurrentUserID(suser);
270        }
271    
272        /**
273         * This method checks the data consistency of the user management and should
274         * be called after a system crash or after importing data from files,
275         * respectively.
276         */
277        public static void checkConsistency() throws Exception {
278            MCRUserMgr.instance().checkConsistency();
279        }
280    
281        /**
282         * This method invokes MCRUserMgr.deleteGroup() and permanently removes a
283         * group from the system.
284         * 
285         * @param groupID
286         *            the ID of the group which will be deleted
287         */
288        public static void deleteGroup(String groupID) throws Exception {
289            MCRUserMgr.instance().deleteGroup(groupID);
290        }
291    
292        /**
293         * This method invokes MCRUserMgr.deleteUser() and permanently removes a
294         * user from the system.
295         * 
296         * @param userID
297         *            the ID of the user which will be deleted
298         */
299        public static void deleteUser(String userID) throws Exception {
300            MCRUserMgr.instance().deleteUser(userID);
301        }
302    
303        /**
304         * This method invokes MCRUserMgr.enableUser() that enables a user
305         * 
306         * @param userID
307         *            the ID of the user which will be enabled
308         */
309        public static void enableUser(String userID) throws Exception {
310            MCRUserMgr.instance().enableUser(userID);
311        }
312    
313        /**
314         * A given XML file containing user data with cleartext passwords must be
315         * converted prior to loading the user data into the system. This method
316         * reads all user objects in the given XML file, encrypts the passwords and
317         * writes them back to a file with name original-file-name_encrypted.xml.
318         * 
319         * @param oldFile
320         *            the filename of the user data input
321         * @param newFile
322         *            the filename of the user data output (encrypted passwords)
323         */
324        public static final void encryptPasswordsInXMLFile(String oldFile, String newFile) throws MCRException {
325            if (!checkFilename(oldFile)) {
326                return;
327            }
328            File input = new File(oldFile);
329    
330            LOGGER.info("Reading file " + input + " ...");
331    
332            try {
333                Document doc = MCRXMLHelper.parseURI(input.toURI(), true);
334                Element rootelm = doc.getRootElement();
335    
336                if (!rootelm.getName().equals("mycoreuser")) {
337                    throw new MCRException("These data do not correspond to a user.");
338                }
339    
340                List<Element> listelm = rootelm.getChildren(); // the <user>
341                // elements
342    
343                for (int i = 0; i < listelm.size(); i++) {
344                    // Get the passwords, encrypt and write it back into the
345                    // document
346                    Element elm = (Element) listelm.get(i);
347                    String passwd = elm.getChildTextTrim("user.password");
348                    String encryptedPasswd = MCRCrypt.crypt(passwd);
349                    elm.getChild("user.password").setText(encryptedPasswd);
350                }
351    
352                FileOutputStream outFile = new FileOutputStream(newFile);
353                saveToXMLFile(doc, outFile);
354            } catch (Exception e) {
355                throw new MCRException("Error while encrypting cleartext passwords in user xml file.", e);
356            }
357        }
358    
359        /**
360         * This method invokes MCRUserMgr.disableUser() that disables a user
361         * 
362         * @param userID
363         *            the ID of the user which will be enabled
364         */
365        public static void disableUser(String userID) throws Exception {
366            MCRUserMgr.instance().disableUser(userID);
367        }
368    
369        /**
370         * This method invokes MCRUserMgr.getAllUserIDs() and retrieves a ArrayList
371         * of all users stored in the persistent datastore.
372         */
373        public static void listAllUsers() throws Exception {
374            List<String> users = MCRUserMgr.instance().getAllUserIDs();
375    
376            for (String uid : users) {
377                listUser(uid);
378            }
379        }
380    
381        /**
382         * This method invokes MCRUserMgr.getAllGroupIDs() and retrieves a ArrayList
383         * of all groups stored in the persistent datastore.
384         */
385        public static void listAllGroups() throws Exception {
386            List<String> groups = MCRUserMgr.instance().getAllGroupIDs();
387    
388            for (String gid : groups) {
389                listGroup(gid);
390            }
391        }
392    
393        /**
394         * This command takes a file name as a parameter, retrieves all groups from
395         * MCRUserMgr as JDOM document and export this to the given file.
396         * 
397         * @param filename
398         *            Name of the file in this the groups will be exported
399         */
400        public static void exportAllGroupsToFile(String filename) throws MCRException {
401            try {
402                Document jdomDoc = MCRUserMgr.instance().getAllGroups();
403                FileOutputStream outFile = new FileOutputStream(filename);
404                LOGGER.info("Writing to file " + filename + " ...");
405                saveToXMLFile(jdomDoc, outFile);
406            } catch (Exception e) {
407                throw new MCRException("Error while command saveAllGroupsToFile()", e);
408            }
409        }
410    
411        /**
412         * This command takes a file name as a parameter, retrieves all users from
413         * MCRUserMgr as JDOM document and export this to the given file.
414         * 
415         * @param filename
416         *            Name of the file in this the users will be exported
417         */
418        public static void exportAllUsersToFile(String filename) throws MCRException {
419            try {
420                Document jdomDoc = MCRUserMgr.instance().getAllUsers();
421                FileOutputStream outFile = new FileOutputStream(filename);
422                LOGGER.info("Writing to file " + filename + " ...");
423                saveToXMLFile(jdomDoc, outFile);
424            } catch (Exception e) {
425                throw new MCRException("Error while command saveAllUsersToFile()", e);
426            }
427        }
428    
429        /**
430         * This command takes a groupID and file name as a parameter, retrieves the
431         * group from MCRUserMgr as JDOM document and export this to the given file.
432         * 
433         * @param groupID
434         *            ID of the group to be saved
435         * @param filename
436         *            Name of the file to store the exported group
437         */
438        public static void exportGroupToFile(String groupID, String filename) throws Exception {
439            try {
440                MCRGroup group = MCRUserMgr.instance().retrieveGroup(groupID);
441                Document jdomDoc = group.toJDOMDocument();
442                Element elmroot = jdomDoc.getRootElement();
443                Element elmgroup = elmroot.getChild("group");
444                Element elmmember = elmgroup.getChild("group.members");
445                if (elmmember != null) {
446                    elmgroup.removeChild("group.members");
447                }
448                FileOutputStream outFile = new FileOutputStream(filename);
449                LOGGER.info("Writing to file " + filename + " ...");
450                saveToXMLFile(jdomDoc, outFile);
451            } catch (Exception e) {
452                throw new MCRException("Error while command saveGroupToFile()", e);
453            }
454        }
455    
456        /**
457         * This command takes a userID and file name as a parameter, retrieves the
458         * user from MCRUserMgr as JDOM document and export this to the given file.
459         * 
460         * @param userID
461         *            ID of the user to be saved
462         * @param filename
463         *            Name of the file to store the exported user
464         */
465        public static void exportUserToFile(String userID, String filename) throws MCRException {
466            try {
467                MCRUser user = MCRUserMgr.instance().retrieveUser(userID);
468                Document jdomDoc = user.toJDOMDocument();
469                FileOutputStream outFile = new FileOutputStream(filename);
470                LOGGER.info("Writing to file " + filename + " ...");
471                saveToXMLFile(jdomDoc, outFile);
472            } catch (Exception e) {
473                throw new MCRException("Error while command saveUserToFile()", e);
474            }
475        }
476    
477        /**
478         * This method invokes MCRUserMgr.retrieveUser() and then works with the
479         * retrieved user object to change the password.
480         * 
481         * @param userID
482         *            the ID of the user for which the password will be set
483         */
484        public static void setPassword(String userID, String password) throws MCRException {
485            MCRUserMgr.instance().setPassword(userID, password);
486        }
487    
488        /**
489         * This method sets the user management component to read only mode
490         */
491        public static void setLock() throws MCRException {
492            MCRUserMgr.instance().setLock(true);
493        }
494    
495        /**
496         * This method sets the user management component to read/write access mode
497         */
498        public static void unLock() throws MCRException {
499            MCRUserMgr.instance().setLock(false);
500        }
501    
502        /**
503         * This method invokes MCRUserMgr.retrieveGroup() and then works with the
504         * retrieved group object to get an XML-Representation.
505         * 
506         * @param groupID
507         *            the ID of the group for which the XML-representation is needed
508         */
509        public static final void listGroup(String groupID) throws MCRException {
510            MCRGroup group = MCRUserMgr.instance().retrieveGroup(groupID);
511            StringBuffer sb = new StringBuffer();
512            LOGGER.info("");
513            sb.append("       group=").append(group.getID());
514            LOGGER.info(sb.toString());
515            ArrayList<String> ar = group.getMemberUserIDs();
516            for (int i = 0; i < ar.size(); i++) {
517                sb = new StringBuffer();
518                sb.append("          user in this group=").append((String) ar.get(i));
519                LOGGER.info(sb.toString());
520            }
521            LOGGER.info("");
522        }
523    
524        /**
525         * This method invokes MCRUserMgr.retrieveUser() and then works with the
526         * retrieved user object to get an XML-Representation.
527         * 
528         * @param userID
529         *            the ID of the user for which the XML-representation is needed
530         */
531        public static final void listUser(String userID) throws MCRException {
532            MCRUser user = MCRUserMgr.instance().retrieveUser(userID);
533            LOGGER.info("");
534            StringBuffer sb = new StringBuffer();
535            sb.append("       user=").append(user.getID()).append("   real name=").append(user.getUserContact().getFirstName()).append(' ')
536                    .append(user.getUserContact().getLastName());
537            LOGGER.info(sb.toString());
538            sb = new StringBuffer();
539            sb.append("          number=").append(user.getNumID()).append("   update=").append(user.isUpdateAllowed()).append("   enabled=")
540                    .append(user.isEnabled());
541            LOGGER.info(sb.toString());
542            sb = new StringBuffer();
543            sb.append("          primary group=").append(user.getPrimaryGroupID());
544            LOGGER.info(sb.toString());
545            List<String> groups = user.getAllGroupIDs();
546            for (String gid : groups) {
547                sb = new StringBuffer();
548                sb.append("          member in group=").append(gid);
549                LOGGER.info(sb.toString());
550            }
551            LOGGER.info("");
552        }
553    
554        /**
555         * Check the file name
556         * 
557         * @param filename
558         *            the filename of the user data input
559         * @return true if the file name is okay
560         */
561        private static final boolean checkFilename(String filename) {
562            if (!filename.endsWith(".xml")) {
563                LOGGER.warn(filename + " ignored, does not end with *.xml");
564    
565                return false;
566            }
567    
568            if (!new File(filename).isFile()) {
569                LOGGER.warn(filename + " ignored, is not a file.");
570    
571                return false;
572            }
573    
574            return true;
575        }
576    
577        /**
578         * This method invokes MCRUserMgr.createUser() with data from a file.
579         * 
580         * @param filename
581         *            the filename of the user data input
582         */
583        public static final void createUserFromFile(String filename) {
584            String useCrypt = CONFIG.getString("MCR.Users.UsePasswordEncryption", "false");
585            boolean useEncryption = (useCrypt.trim().equals("true")) ? true : false;
586            createUserFromFile(filename, useEncryption);
587        }
588    
589        /**
590         * This method invokes MCRUserMgr.createUser() with data from a file.
591         * 
592         * @param filename
593         *            the filename of the user data input
594         * @param useEncryption
595         *            flag to determine whether we use password encryption or not
596         */
597        private static final void createUserFromFile(String filename, boolean useEncryption) throws MCRException {
598            MCRUserMgr mcrUserMgr = MCRUserMgr.instance();
599            if (!checkFilename(filename)) {
600                return;
601            }
602            File input = new File(filename);
603            LOGGER.info("Reading file " + input + " ...");
604    
605            try {
606                Document doc = MCRXMLHelper.parseURI(input.toURI(), true);
607                Element rootelm = doc.getRootElement();
608    
609                if (!rootelm.getName().equals("mycoreuser")) {
610                    throw new MCRException("The data are not for user.");
611                }
612    
613                List<Element> listelm = rootelm.getChildren();
614    
615                for (int i = 0; i < listelm.size(); i++) {
616                    MCRUser u = new MCRUser((Element) listelm.get(i), useEncryption);
617                    if (!mcrUserMgr.existUser(u.getID())) {
618                        mcrUserMgr.createUser(u);
619                    } else {
620                        LOGGER.info("User " + u.getID() + " was not created, because it already exists.");
621                    }
622                }
623            } catch (Exception e) {
624                throw new MCRException("Error while loading user data.", e);
625            }
626        }
627    
628        /**
629         * This method invokes MCRUserMgr.createGroup() with data from a file.
630         * 
631         * @param filename
632         *            the filename of the user data input
633         */
634        public static final void createGroupFromFile(String filename) throws MCRException {
635            MCRUserMgr mcrUserMgr = MCRUserMgr.instance();
636            if (!checkFilename(filename)) {
637                return;
638            }
639    
640            File input = new File(filename);
641            LOGGER.info("Reading file " + input + " ...");
642    
643            try {
644                Document doc = MCRXMLHelper.parseURI(input.toURI(), true);
645                Element rootelm = doc.getRootElement();
646    
647                if (!rootelm.getName().equals("mycoregroup")) {
648                    throw new MCRException("The data are not for group.");
649                }
650    
651                List<Element> listelm = rootelm.getChildren();
652    
653                for (int i = 0; i < listelm.size(); i++) {
654                    MCRGroup g = new MCRGroup((Element) listelm.get(i));
655                    if (!mcrUserMgr.existGroup(g.getID())) {
656                        MCRUserMgr.instance().createGroup(g);
657                    } else {
658                        LOGGER.info("Group " + g.getID() + " was not created, because it already exists.");
659                    }
660                }
661            } catch (Exception e) {
662                throw new MCRException("Error while loading group data.", e);
663            }
664        }
665    
666        /**
667         * This method imports groups and user data from XML files. It simply call
668         * createGroupFromFile() of the MCRUserManager.
669         * 
670         * @param groupFileName
671         *            the filename of the group data input
672         * @param userFileName
673         *            the filename of the user data input
674         */
675        public static final void importUserSystemFromFiles(String groupFileName, String userFileName) throws MCRException {
676            // check file names
677            if (!checkFilename(groupFileName)) {
678                return;
679            }
680            if (!checkFilename(userFileName)) {
681                return;
682            }
683            MCRUserMgr umgr = MCRUserMgr.instance();
684            try {
685                // read groups
686                File groupFile = new File(groupFileName);
687                LOGGER.info("Reading group file " + groupFile + " ...");
688                Document groupdoc = MCRXMLHelper.parseURI(groupFile.toURI(), true);
689                Element grouprootelm = groupdoc.getRootElement();
690                if (!grouprootelm.getName().equals("mycoregroup")) {
691                    throw new MCRException("The data are not for group.");
692                }
693                // read users
694                File userfILE = new File(userFileName);
695                LOGGER.info("Reading user file " + userfILE + " ...");
696                Document userdoc = MCRXMLHelper.parseURI(userfILE.toURI(), true);
697                Element userrootelm = userdoc.getRootElement();
698                if (!userrootelm.getName().equals("mycoreuser")) {
699                    throw new MCRException("The data are not for user.");
700                }
701                umgr.importUserSystemFromFiles(grouprootelm, userrootelm);
702                // check the consistency
703                umgr.checkConsistency();
704            } catch (Exception e) {
705                LOGGER.error("Error while loading group and user data.");
706                LOGGER.error(e.getMessage());
707                if (LOGGER.isDebugEnabled()) {
708                    e.printStackTrace();
709                }
710            }
711    
712        }
713    
714        /**
715         * This method invokes MCRUserMgr.updateUser() with data from a file.
716         * 
717         * @param filename
718         *            the filename of the user data input
719         */
720        public static final void updateUserFromFile(String filename) {
721            String useCrypt = CONFIG.getString("MCR.Users.UsePasswordEncryption", "false");
722            boolean useEncryption = (useCrypt.trim().equals("true")) ? true : false;
723            updateUserFromFile(filename, useEncryption);
724        }
725    
726        /**
727         * This method invokes MCRUserMgr.updateUser() with data from a file.
728         * 
729         * @param filename
730         *            the filename of the user data input
731         * @param useEncryption
732         *            flag to determine whether we use password encryption or not
733         */
734        private static final void updateUserFromFile(String filename, boolean useEncryption) throws MCRException {
735            if (!checkFilename(filename)) {
736                return;
737            }
738            File input = new File(filename);
739            LOGGER.info("Reading file " + input + " ...");
740    
741            try {
742                Document doc = MCRXMLHelper.parseURI(input.toURI(), true);
743                Element rootelm = doc.getRootElement();
744    
745                if (!rootelm.getName().equals("mycoreuser")) {
746                    throw new MCRException("These data are not defining a user.");
747                }
748    
749                List<Element> listelm = rootelm.getChildren();
750    
751                for (int i = 0; i < listelm.size(); i++) {
752                    MCRUser u = new MCRUser((Element) listelm.get(i), useEncryption);
753                    MCRUserMgr.instance().updateUser(u);
754                }
755            } catch (Exception e) {
756                throw new MCRException("Error while updating a user from file.", e);
757            }
758        }
759    
760        /**
761         * This method adds a user as a member to a group
762         * 
763         * @param mbrUserID
764         *            the ID of the user which will be a member of the group
765         *            represented by groupID
766         * @param groupID
767         *            the ID of the group to which the user with ID mbrUserID will
768         *            be added
769         * @throws MCRException
770         */
771        public static final void addMemberUserToGroup(String mbrUserID, String groupID) throws MCRException {
772            try {
773                MCRGroup group = MCRUserMgr.instance().retrieveGroup(groupID);
774                group.addMemberUserID(mbrUserID);
775                MCRUserMgr.instance().updateGroup(group);
776            } catch (Exception e) {
777                throw new MCRException("Error while adding group " + mbrUserID + " to group " + groupID + ".", e);
778            }
779        }
780    
781        /**
782         * This method removes a member user from a group
783         * 
784         * @param mbrUserID
785         *            the ID of the user which will be removed from the group
786         *            represented by groupID
787         * @param groupID
788         *            the ID of the group from which the user with ID mbrUserID will
789         *            be removed
790         * @throws MCRException
791         */
792        public static final void removeMemberUserFromGroup(String mbrUserID, String groupID) throws MCRException {
793            try {
794                MCRGroup group = MCRUserMgr.instance().retrieveGroup(groupID);
795                group.removeMemberUserID(mbrUserID);
796                MCRUserMgr.instance().updateGroup(group);
797            } catch (Exception e) {
798                throw new MCRException("Error while removing group " + mbrUserID + " from group " + groupID + ".", e);
799            }
800        }
801    
802        /**
803         * This method just saves a JDOM document to a file
804         * 
805         * @param jdomDoc
806         *            the JDOM XML document to be printed
807         * @param outFile
808         *            a FileOutputStream object for the output
809         */
810        private static final void saveToXMLFile(Document jdomDoc, FileOutputStream outFile) throws MCRException {
811            String mcr_encoding = CONFIG.getString("MCR.Metadata.DefaultEncoding", DEFAULT_ENCODING);
812    
813            // Create the output
814            XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat().setEncoding(mcr_encoding));
815    
816            try {
817                outputter.output(jdomDoc, outFile);
818            } catch (Exception e) {
819                throw new MCRException("Error while save XML to file.");
820            }
821        }
822    }