📄 xmluserdatabase.java
字号:
{ throw new WikiSecurityException( e.getLocalizedMessage() ); } // Copy new file over old version File backup = new File( c_file.getAbsolutePath() + ".old" ); if ( backup.exists() ) { if ( !backup.delete() ) { log.error( "Could not delete old user database backup: " + backup ); } } if ( !c_file.renameTo( backup ) ) { log.error( "Could not create user database backup: " + backup ); } if ( !newFile.renameTo( c_file ) ) { log.error( "Could not save database: " + backup + " restoring backup." ); if ( !backup.renameTo( c_file ) ) { log.error( "Restore failed. Check the file permissions." ); } log.error( "Could not save database: " + c_file + ". Check the file permissions" ); } } private long c_lastCheck = 0; private long c_lastModified = 0; private void checkForRefresh() { long time = System.currentTimeMillis(); if( time - c_lastCheck > 60*1000L ) { long lastModified = c_file.lastModified(); if( lastModified > c_lastModified ) { buildDOM(); } } } /** * @see com.ecyrd.jspwiki.auth.user.UserDatabase#rename(String, String) */ public synchronized void rename(String loginName, String newName) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException { if ( c_dom == null ) { log.fatal( "Could not rename profile '" + loginName + "'; database does not exist" ); throw new IllegalStateException( "FATAL: database does not exist" ); } checkForRefresh(); // Get the existing user; if not found, throws NoSuchPrincipalException UserProfile profile = findByLoginName( loginName ); // Get user with the proposed name; if found, it's a collision try { UserProfile otherProfile = findByLoginName( newName ); if ( otherProfile != null ) { throw ( new DuplicateUserException( "Cannot rename: the login name '" + newName + "' is already taken." ) ); } } catch ( NoSuchPrincipalException e ) { // Good! That means it's safe to save using the new name } // Find the user with the old login id attribute, and change it NodeList users = c_dom.getElementsByTagName( USER_TAG ); for( int i = 0; i < users.getLength(); i++ ) { Element user = (Element) users.item( i ); if ( user.getAttribute( LOGIN_NAME ).equals( loginName ) ) { Date modDate = new Date( System.currentTimeMillis() ); setAttribute( user, LOGIN_NAME, newName ); setAttribute( user, LAST_MODIFIED, c_format.format( modDate ) ); profile.setLoginName( newName ); profile.setLastModified( modDate ); break; } } // Commit to disk saveDOM(); } /** * Saves a {@link UserProfile}to the user database, overwriting the * existing profile if it exists. The user name under which the profile * should be saved is returned by the supplied profile's * {@link UserProfile#getLoginName()}method. * @param profile the user profile to save * @throws WikiSecurityException if the profile cannot be saved */ public synchronized void save( UserProfile profile ) throws WikiSecurityException { if ( c_dom == null ) { log.fatal( "Could not save profile " + profile + " database does not exist" ); throw new IllegalStateException( "FATAL: database does not exist" ); } checkForRefresh(); String index = profile.getLoginName(); NodeList users = c_dom.getElementsByTagName( USER_TAG ); Element user = null; for( int i = 0; i < users.getLength(); i++ ) { Element currentUser = (Element) users.item( i ); if ( currentUser.getAttribute( LOGIN_NAME ).equals( index ) ) { user = currentUser; break; } } boolean isNew = false; Date modDate = new Date( System.currentTimeMillis() ); if( user == null ) { // Create new user node profile.setCreated( modDate ); log.info( "Creating new user " + index ); user = c_dom.createElement( USER_TAG ); c_dom.getDocumentElement().appendChild( user ); setAttribute( user, CREATED, c_format.format( profile.getCreated() ) ); isNew = true; } else { // To update existing user node, delete old attributes first... NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG ); for ( int i = 0; i < attributes.getLength(); i++ ) { user.removeChild( attributes.item( i ) ); } } setAttribute( user, UID, profile.getUid() ); setAttribute( user, LAST_MODIFIED, c_format.format( modDate ) ); setAttribute( user, LOGIN_NAME, profile.getLoginName() ); setAttribute( user, FULL_NAME, profile.getFullname() ); setAttribute( user, WIKI_NAME, profile.getWikiName() ); setAttribute( user, EMAIL, profile.getEmail() ); Date lockExpiry = profile.getLockExpiry(); setAttribute( user, LOCK_EXPIRY, lockExpiry == null ? "" : c_format.format( lockExpiry ) ); // Hash and save the new password if it's different from old one String newPassword = profile.getPassword(); if ( newPassword != null && !newPassword.equals( "" ) ) { String oldPassword = user.getAttribute( PASSWORD ); if ( !oldPassword.equals( newPassword ) ) { setAttribute( user, PASSWORD, getHash( newPassword ) ); } } // Save the attributes as as Base64 string if ( profile.getAttributes().size() > 0 ) { try { String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes() ); Element attributes = c_dom.createElement( ATTRIBUTES_TAG ); user.appendChild( attributes ); Text value = c_dom.createTextNode( encodedAttributes ); attributes.appendChild( value ); } catch ( IOException e ) { throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage() ); } } // Set the profile timestamps if ( isNew ) { profile.setCreated( modDate ); } profile.setLastModified( modDate ); // Commit to disk saveDOM(); } /** * Private method that returns the first {@link UserProfile}matching a * <user> element's supplied attribute. This method will also * set the UID if it has not yet been set. * @param matchAttribute * @param index * @return the profile, or <code>null</code> if not found */ private UserProfile findByAttribute( String matchAttribute, String index ) { if ( c_dom == null ) { throw new IllegalStateException( "FATAL: database does not exist" ); } checkForRefresh(); NodeList users = c_dom.getElementsByTagName( USER_TAG ); if( users == null ) return null; for( int i = 0; i < users.getLength(); i++ ) { Element user = (Element) users.item( i ); if ( user.getAttribute( matchAttribute ).equals( index ) ) { UserProfile profile = newProfile(); // Parse basic attributes profile.setUid( user.getAttribute( UID ) ); if ( profile.getUid() == null || profile.getUid().length() == 0 ) { profile.setUid( generateUid( this ) ); } profile.setLoginName( user.getAttribute( LOGIN_NAME ) ); profile.setFullname( user.getAttribute( FULL_NAME ) ); profile.setPassword( user.getAttribute( PASSWORD ) ); profile.setEmail( user.getAttribute( EMAIL ) ); // Get created/modified timestamps String created = user.getAttribute( CREATED ); String modified = user.getAttribute( LAST_MODIFIED ); profile.setCreated( parseDate( profile, created ) ); profile.setLastModified( parseDate( profile, modified ) ); // Is the profile locked? String lockExpiry = user.getAttribute( LOCK_EXPIRY ); if ( lockExpiry == null || lockExpiry.length() == 0 ) { profile.setLockExpiry( null ); } else { profile.setLockExpiry( new Date( Long.parseLong( lockExpiry ) ) ); } // Extract all of the user's attributes (should only be one attributes tag, but you never know!) NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG ); for ( int j = 0; j < attributes.getLength(); j++ ) { Element attribute = (Element)attributes.item( j ); String serializedMap = extractText( attribute ); try { Map<String,? extends Serializable> map = Serializer.deserializeFromBase64( serializedMap ); profile.getAttributes().putAll( map ); } catch ( IOException e ) { log.error( "Could not parse user profile attributes!", e ); } } return profile; } } return null; } /** * Extracts all of the text nodes that are immediate children of an Element. * @param element the base element * @return the text nodes that are immediate children of the base element, concatenated together */ private String extractText( Element element ) { String text = ""; if ( element.getChildNodes().getLength() > 0 ) { NodeList children = element.getChildNodes(); for ( int k = 0; k < children.getLength(); k++ ) { Node child = children.item( k ); if ( child.getNodeType() == Node.TEXT_NODE ) { text = text + ((Text)child).getData(); } } } return text; } /** * Tries to parse a date using the default format - then, for backwards * compatibility reasons, tries the platform default. * * @param profile * @param date * @return A parsed date, or null, if both parse attempts fail. */ private Date parseDate( UserProfile profile, String date ) { try { return c_format.parse( date ); } catch( ParseException e ) { try { return c_defaultFormat.parse( date ); } catch ( ParseException e2) { log.warn("Could not parse 'created' or 'lastModified' " + "attribute for " + " profile '" + profile.getLoginName() + "'." + " It may have been tampered with." ); } } return null; } /** * After loading the DOM, this method sanity-checks the dates in the DOM and makes * sure they are formatted properly. This is sort-of hacky, but it should work. */ private void sanitizeDOM() { if ( c_dom == null ) { throw new IllegalStateException( "FATAL: database does not exist" ); } NodeList users = c_dom.getElementsByTagName( USER_TAG ); for( int i = 0; i < users.getLength(); i++ ) { Element user = (Element) users.item( i ); // Sanitize UID (and generate a new one if one does not exist) String uid = user.getAttribute( UID ).trim(); if ( uid == null || uid.length() == 0 || "-1".equals( uid ) ) { uid = String.valueOf( generateUid( this ) ); user.setAttribute( UID, uid ); } // Sanitize dates String loginName = user.getAttribute( LOGIN_NAME ); String created = user.getAttribute( CREATED ); String modified = user.getAttribute( LAST_MODIFIED ); try { created = c_format.format( c_format.parse( created ) ); modified = c_format.format( c_format.parse( modified ) ); user.setAttribute( CREATED, created ); user.setAttribute( LAST_MODIFIED, modified ); } catch( ParseException e ) { try { created = c_format.format( c_defaultFormat.parse( created ) ); modified = c_format.format( c_defaultFormat.parse( modified ) ); user.setAttribute( CREATED, created ); user.setAttribute( LAST_MODIFIED, modified ); } catch ( ParseException e2) { log.warn("Could not parse 'created' or 'lastModified' " + "attribute for " + " profile '" + loginName + "'." + " It may have been tampered with." ); } } } } /** * Private method that sets an attribute value for a supplied DOM element. * @param element the element whose attribute is to be set * @param attribute the name of the attribute to set * @param value the desired attribute value */ private void setAttribute( Element element, String attribute, String value ) { if ( value != null ) { element.setAttribute( attribute, value ); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -