Project: * Clean-up (Eclipse cruft, unused files, etc...) * Git-specific changes * Maven POMs clean-up and changes for the build system * Version set to 1.0.0-0 in the development branches * Maven plug-ins updated to latest versions * Very partial dev. documentation added

This commit is contained in:
Emmanuel BENOîT 2011-12-09 08:07:33 +01:00
parent c74e30d5ba
commit 0665a760de
1439 changed files with 1020 additions and 1649 deletions

View file

@ -0,0 +1,75 @@
package com.deepclone.lw.beans.acm;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class AccountCleanupBean
implements InitializingBean , DisposableBean
{
private TransactionTemplate tTemplate;
private Ticker ticker;
private UsersDAO usersDao;
private Mailer mailer;
private AccountCleanupTask cleanupTask;
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setUsersDAO( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Autowired( required = true )
public void setMailer( Mailer mailer )
{
this.mailer = mailer;
}
@Override
public void afterPropertiesSet( )
throws Exception
{
this.cleanupTask = new AccountCleanupTask( this.tTemplate , this.usersDao , this.mailer );
this.ticker.registerTask( Frequency.MEDIUM , "Accounts clean-up task" , this.cleanupTask );
}
@Override
public void destroy( )
{
this.cleanupTask = null;
}
}

View file

@ -0,0 +1,96 @@
package com.deepclone.lw.beans.acm;
import java.util.List;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.sqld.accounts.QuittingAccount;
class AccountCleanupTask
implements Runnable
{
private TransactionTemplate tTemplate;
private UsersDAO usersDao;
private Mailer mailer;
public AccountCleanupTask( TransactionTemplate tTemplate , UsersDAO usersDao , Mailer mailer )
{
this.tTemplate = tTemplate;
this.usersDao = usersDao;
this.mailer = mailer;
}
@Override
public void run( )
{
this.sendInactivityWarnings( );
this.disableInactiveAccounts( );
this.dropOldAccounts( );
}
private void sendInactivityWarnings( )
{
List< QuittingAccount > toWarn;
toWarn = this.tTemplate.execute( new TransactionCallback< List< QuittingAccount >>( ) {
@Override
public List< QuittingAccount > doInTransaction( TransactionStatus status )
{
return usersDao.getInactivesToWarn( );
}
} );
for ( QuittingAccount account : toWarn ) {
try {
this.mailer.createMail( account.getLanguage( ) , "inactivityWarningMail" , account.getAddress( ) )
.queue( );
} catch ( Exception e ) {
continue;
}
}
}
private void disableInactiveAccounts( )
{
List< QuittingAccount > toDisable;
toDisable = this.tTemplate.execute( new TransactionCallback< List< QuittingAccount >>( ) {
@Override
public List< QuittingAccount > doInTransaction( TransactionStatus status )
{
return usersDao.getInactivesToDisable( );
}
} );
for ( QuittingAccount account : toDisable ) {
try {
this.mailer.createMail( account.getLanguage( ) , "inactivityQuitMail" , account.getAddress( ) ).queue( );
} catch ( Exception e ) {
continue;
}
}
}
private void dropOldAccounts( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
usersDao.deleteOldAccounts( );
}
} );
}
}

View file

@ -0,0 +1,757 @@
package com.deepclone.lw.beans.acm;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.cmd.admin.adata.Administrator;
import com.deepclone.lw.cmd.admin.bans.ValidatedBanRequest;
import com.deepclone.lw.cmd.admin.logs.LogLevel;
import com.deepclone.lw.cmd.admin.users.AccountListEntry;
import com.deepclone.lw.cmd.admin.users.AccountSessionEntry;
import com.deepclone.lw.cmd.admin.users.AccountStatus;
import com.deepclone.lw.cmd.admin.users.AccountViewEntry;
import com.deepclone.lw.cmd.admin.users.SessionTerminationType;
import com.deepclone.lw.cmd.admin.users.UserSession;
import com.deepclone.lw.cmd.ext.ListLanguagesResponse;
import com.deepclone.lw.cmd.player.account.BanDetailsResponse;
import com.deepclone.lw.cmd.player.gdata.account.AccountData;
import com.deepclone.lw.cmd.player.gdata.account.PrefCategory;
import com.deepclone.lw.cmd.player.gdata.account.PrefChoice;
import com.deepclone.lw.cmd.player.gdata.account.PrefType;
import com.deepclone.lw.cmd.player.gdata.account.PrefValue;
import com.deepclone.lw.interfaces.acm.*;
import com.deepclone.lw.interfaces.admin.BansDAO;
import com.deepclone.lw.interfaces.eventlog.*;
import com.deepclone.lw.interfaces.i18n.*;
import com.deepclone.lw.interfaces.mailer.*;
import com.deepclone.lw.interfaces.naming.NamingDAO;
import com.deepclone.lw.interfaces.prefs.Preference;
import com.deepclone.lw.interfaces.prefs.PreferenceGroup;
import com.deepclone.lw.interfaces.prefs.PreferenceType;
import com.deepclone.lw.interfaces.prefs.PreferencesDAO;
import com.deepclone.lw.sqld.accounts.*;
import com.deepclone.lw.utils.*;
public class AccountManagementBean
implements AccountManagement
{
private TransactionTemplate tTemplate;
private Mailer mailer;
private Logger logger;
private UsersDAO usersDao;
private UserSessionDAO sessionDao;
private NamingDAO namingDao;
private Translator translator;
private PreferencesDAO prefsDao;
private BansDAO bansDao;
@Autowired( required = true )
public void setTransactionTemplate( PlatformTransactionManager transactionManager )
{
this.tTemplate = new TransactionTemplate( transactionManager );
}
@Autowired( required = true )
public void setMailer( Mailer mailer )
{
this.mailer = mailer;
}
@Autowired( required = true )
public void setLogger( Logger logger )
{
this.logger = logger;
}
@Autowired( required = true )
public void setUsersDao( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Autowired( required = true )
public void setSessionDao( UserSessionDAO sessionDao )
{
this.sessionDao = sessionDao;
}
@Autowired( required = true )
public void setNamingDao( NamingDAO namingDao )
{
this.namingDao = namingDao;
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Autowired( required = true )
public void setPrefsDao( PreferencesDAO prefsDao )
{
this.prefsDao = prefsDao;
}
@Autowired( required = true )
public void setBansDao( BansDAO bansDao )
{
this.bansDao = bansDao;
}
@Override
public void createAccount( final EmailAddress address , final Password password , final String language )
throws AccountMailException , MailerException , TranslationException
{
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
sLog.log( LogLevel.INFO , "Attempting to create account '" + address.getAddress( ) + "'" ).flush( );
// Create credentials
AccountOperationResult result;
result = this.tTemplate.execute( new TransactionCallback< AccountOperationResult >( ) {
@Override
public AccountOperationResult doInTransaction( TransactionStatus status )
{
AccountOperationResult r = usersDao.createAccount( address , password , language );
if ( r.getErrorCode( ) != 0 ) {
status.setRollbackOnly( );
}
return r;
}
} );
// Check creation status
switch ( result.getErrorCode( ) ) {
case 0:
break;
case -1:
sLog.log( LogLevel.INFO , "Could not create account '" + address.getAddress( ) + "' - it exists" )
.flush( );
throw new AccountMailException( );
case -2:
sLog
.log( LogLevel.INFO ,
"Could not create account '" + address.getAddress( ) + "' - unknown language" ).flush( );
throw new UnknownLanguageException( language );
default:
sLog.log(
LogLevel.ERROR ,
"Could not create account '" + address.getAddress( ) + "' - unknown error code "
+ result.getErrorCode( ) ).flush( );
throw new RuntimeException( );
}
// Send email
Account account = result.getAccount( );
MailData data = this.mailer.createMail( language , "registrationMail" , address.getAddress( ) );
data.setData( "address" , address.getAddress( ) );
data.setData( "validationKey" , account.getValidationToken( ) );
try {
data.sendNow( );
} catch ( MailerException e ) {
this.cancelValidation( account );
sLog.log( LogLevel.INFO , "Could not create account '" + address.getAddress( ) + "'" , e ).flush( );
if ( e instanceof NotSentException ) {
throw e;
}
throw new RuntimeException( e );
}
}
private void cancelValidation( final Account account )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
usersDao.cancelAccountValidation( account );
}
} );
}
@Override
public void reactivateAccount( final EmailAddress address )
throws AccountMailException , MailerException
{
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
sLog.log( LogLevel.INFO , "trying to re-activate account " + address.getAddress( ) ).flush( );
// Check status
Account account = this.tTemplate.execute( new TransactionCallback< Account >( ) {
@Override
public Account doInTransaction( TransactionStatus status )
{
Account r = usersDao.reactivateAccount( address );
if ( r == null ) {
status.setRollbackOnly( );
}
return r;
}
} );
if ( account == null ) {
throw new AccountMailException( );
}
// Send email
MailData data;
try {
data = this.mailer.createMail( account.getLanguage( ) , "reactivationMail" , address.getAddress( ) );
} catch ( TranslationException e ) {
sLog.log( LogLevel.ERROR , "'" + address.getAddress( ) + "' - error while preparing reactivation mail" , e )
.flush( );
this.cancelValidation( account );
throw new RuntimeException( e );
}
data.setData( "address" , account.getAddress( ) );
data.setData( "token" , account.getValidationToken( ) );
try {
data.sendNow( );
} catch ( MailerException e ) {
this.cancelValidation( account );
if ( e instanceof NotSentException ) {
throw e;
}
throw new RuntimeException( e );
}
}
@Override
public ValidationResult validateAccount( final EmailAddress address , final String token , final String empire ,
final String planet )
{
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
sLog.log( LogLevel.INFO , "trying to validate account '" + address.getAddress( ) + "'" ).flush( );
return this.tTemplate.execute( new TransactionCallback< ValidationResult >( ) {
@Override
public ValidationResult doInTransaction( TransactionStatus status )
{
ValidationResult r = usersDao.validateAccount( address , token , empire , planet );
if ( r.isError( ) ) {
status.setRollbackOnly( );
}
return r;
}
} );
}
@Override
public void requestPasswordRecovery( final EmailAddress address )
throws AccountMailException , MailerException , PasswordRecoveryException
{
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
sLog.log( LogLevel.INFO , "'" + address.getAddress( ) + "' requesting password recovery" ).flush( );
AccountOperationResult result = this.tTemplate.execute( new TransactionCallback< AccountOperationResult >( ) {
@Override
public AccountOperationResult doInTransaction( TransactionStatus status )
{
AccountOperationResult r = usersDao.requestPasswordRecovery( address );
if ( r.getErrorCode( ) != 0 ) {
status.setRollbackOnly( );
}
return r;
}
} );
// Throw exceptions as needed
switch ( result.getErrorCode( ) ) {
case 0:
break;
case 1:
sLog.log( LogLevel.INFO , "'" + address.getAddress( ) + "' - duplicate password recovery request" )
.flush( );
throw new PasswordRecoveryException( false );
case 2:
sLog.log( LogLevel.INFO , "'" + address.getAddress( ) + "' - account does not exist" ).flush( );
throw new AccountMailException( );
default:
sLog.log( LogLevel.ERROR , "Unknown error code " + result.getErrorCode( ) ).flush( );
throw new RuntimeException( );
}
// Send email
MailData data;
Account account = result.getAccount( );
try {
data = this.mailer.createMail( account.getLanguage( ) , "passwordRecoveryMail" , address.getAddress( ) );
} catch ( TranslationException e ) {
sLog.log( LogLevel.ERROR , "'" + address.getAddress( ) + "' - error while preparing recovery mail" , e )
.flush( );
this.cancelPasswordRecovery( account );
throw new RuntimeException( e );
}
data.setData( "address" , address.getAddress( ) );
data.setData( "token" , account.getPwdRecoveryToken( ) );
try {
data.sendNow( );
} catch ( MailerException e ) {
this.cancelPasswordRecovery( account );
if ( e instanceof NotSentException ) {
throw e;
}
throw new RuntimeException( e );
}
}
private void cancelPasswordRecovery( final Account account )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
usersDao.cancelPasswordRecovery( account );
}
} );
}
@Override
public void recoverPassword( final EmailAddress address , final String token , final Password password )
throws AccountMailException , PasswordRecoveryException , PasswordProhibitedException
{
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
sLog.log( LogLevel.INFO , "'" + address.getAddress( ) + "' confirming password recovery" ).flush( );
AccountOperationResult result = this.tTemplate.execute( new TransactionCallback< AccountOperationResult >( ) {
@Override
public AccountOperationResult doInTransaction( TransactionStatus status )
{
AccountOperationResult r = usersDao.confirmPasswordRecovery( address , token , password );
if ( r.getErrorCode( ) != 0 ) {
status.setRollbackOnly( );
}
return r;
}
} );
// Handle errors
switch ( result.getErrorCode( ) ) {
case 0:
break;
case 1:
throw new AccountMailException( );
case 2:
throw new PasswordProhibitedException( );
default:
sLog.log( LogLevel.ERROR , "Unknown error code " + result.getErrorCode( ) ).flush( );
throw new RuntimeException( );
}
}
@Override
@Transactional
public AccountSession login( final EmailAddress address , String challenge , String sha1Hash , String md5Hash ,
InetAddress ipAddress , String clientType , String sessionName )
{
Account account = this.usersDao.getAccount( address );
// Check account
if ( account == null ) {
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
sLog.log( LogLevel.INFO , "login attempt for unknown address '" + address.getAddress( ) + "'" ).flush( );
return null;
}
// Check challenge response
String eSha1 = DigestHelper.digest( "sha-1" , challenge + " " + account.getPassSha1( ) );
String eMd5 = DigestHelper.digest( "md5" , challenge + " " + account.getPassMd5( ) );
if ( ! ( eSha1.equals( sha1Hash ) && eMd5.equals( md5Hash ) ) ) {
return null;
}
// Create session
long sId = this.sessionDao.startSession( account.getId( ) , sessionName , clientType , ipAddress.toString( ) );
return new AccountSession( account , sId );
}
@Override
@Transactional
public void logout( long session , SessionTerminationType reason )
{
this.sessionDao.endSession( session , reason );
}
@Override
@Transactional
public Account restoreSession( long session )
{
UserSession sData = this.sessionDao.getSession( session );
if ( sData == null || sData.getEndType( ) != null ) {
return null;
}
return this.usersDao.getAccount( sData.getCredentialsId( ) );
}
@Override
@Transactional
public Account getAccount( final EmailAddress address )
{
return this.usersDao.getAccount( address );
}
@Override
@Transactional
public List< String > getEmpireNames( final EmailAddress address )
{
Account accnt = this.usersDao.getAccount( address );
if ( accnt == null ) {
return null;
}
return this.namingDao.getEmpireNames( accnt.getId( ) );
}
@Override
@Transactional
public AccountData getAccountPage( EmailAddress address )
{
Account account = this.getAccount( address );
return this.accountToPage( account );
}
private AccountData accountToPage( Account account )
{
AccountData data = new AccountData( );
data.setAddress( account.getAddress( ) );
data.setGameCredits( account.getGameCredits( ) );
data.setLanguage( account.getLanguage( ) );
data.setQuitGame( account.getInactivityStart( ) );
data.setVacCredits( account.getVacationCredits( ) );
data.setVacTime( account.getVacationTime( ) );
data.setVacStart( account.getVacationStart( ) );
data.setMailChange( this.usersDao.getMailChange( account.getId( ) ) );
// Get supported languages
Map< String , String > languages = new HashMap< String , String >( );
try {
for ( String lId : this.translator.getSupportedLanguages( ) ) {
languages.put( lId , this.translator.getLanguageName( lId ) );
}
} catch ( UnknownLanguageException e ) {
throw new RuntimeException( e );
}
data.setSupportedLanguages( new ListLanguagesResponse( languages ) );
// Extract account preferences
for ( PreferenceGroup group : this.prefsDao.getPreferences( account ).getGroups( ) ) {
PrefCategory pCat = new PrefCategory( );
pCat.setName( group.getDisplay( ) );
for ( Preference pref : group.getPreferences( ) ) {
PrefValue pValue = new PrefValue( );
pValue.setId( pref.getName( ) );
pValue.setName( pref.getDisplayName( ) );
pValue.setDescription( pref.getDescription( ) );
PreferenceType< ? > dType = pref.getType( );
if ( dType.getType( ) == String.class ) {
pValue.setType( PrefType.STRING );
} else if ( dType.getType( ) == Integer.class ) {
pValue.setType( PrefType.INTEGER );
} else if ( dType.getType( ) == Boolean.class ) {
pValue.setType( PrefType.BOOLEAN );
} else {
Map< String , String > choices = dType.getChoices( );
List< PrefChoice > cList = new LinkedList< PrefChoice >( );
for ( Map.Entry< String , String > entry : choices.entrySet( ) ) {
String name;
try {
name = this.translator.translate( data.getLanguage( ) , entry.getValue( ) );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
cList.add( new PrefChoice( entry.getKey( ) , name ) );
}
pValue.setType( PrefType.CHOICE );
pValue.setChoices( cList );
}
pValue.setValue( pref.getDBValue( ) );
pCat.addValue( pValue );
}
data.addPreferenceCategory( pCat );
}
return data;
}
@Override
@Transactional
public void setLanguage( EmailAddress address , String language )
{
this.usersDao.setLanguage( address , language );
}
@Override
@Transactional
public boolean setPassword( final EmailAddress address , String challenge , String sha1Hash , String md5Hash ,
Password newPassword )
throws PasswordProhibitedException
{
Account account = this.usersDao.getAccount( address );
// Check challenge response
String eSha1 = DigestHelper.digest( "sha-1" , challenge + " " + account.getPassSha1( ) );
String eMd5 = DigestHelper.digest( "md5" , challenge + " " + account.getPassMd5( ) );
if ( ! ( eSha1.equals( sha1Hash ) && eMd5.equals( md5Hash ) ) ) {
return false;
}
if ( !this.usersDao.setPassword( account , newPassword ) ) {
throw new PasswordProhibitedException( );
}
return true;
}
@Override
@Transactional( rollbackFor = {
RuntimeException.class , AccountMailException.class , MailerException.class
} )
public boolean setAddress( EmailAddress address , String challenge , String sha1Hash , String md5Hash ,
EmailAddress nAddress )
throws AccountMailException , MailerException
{
Account account = this.usersDao.getAccount( address );
// Check challenge response
String eSha1 = DigestHelper.digest( "sha-1" , challenge + " " + account.getPassSha1( ) );
String eMd5 = DigestHelper.digest( "md5" , challenge + " " + account.getPassMd5( ) );
if ( ! ( eSha1.equals( sha1Hash ) && eMd5.equals( md5Hash ) ) ) {
return false;
}
int errCode = this.usersDao.setAddress( account , nAddress );
switch ( errCode ) {
case -1:
return true;
case -2:
throw new AccountMailException( );
}
// Send email
SystemLogger sLog = this.logger.getSystemLogger( "AccountManagement" );
MailData data;
account = this.usersDao.getAccount( address );
try {
data = this.mailer.createMail( account.getLanguage( ) , "addressChangeMail" , nAddress.getAddress( ) );
} catch ( TranslationException e ) {
sLog.log( LogLevel.ERROR , "'" + address.getAddress( ) + "' - error while preparing recovery mail" , e )
.flush( );
this.cancelPasswordRecovery( account );
throw new RuntimeException( e );
}
data.setData( "address" , nAddress.getAddress( ) );
data.setData( "token" , account.getAddressChangeToken( ) );
try {
data.sendNow( );
} catch ( MailerException e ) {
if ( e instanceof NotSentException ) {
throw e;
}
throw new RuntimeException( e );
}
return true;
}
@Override
@Transactional
public void cancelAddressChange( EmailAddress cAddress )
{
this.usersDao.cancelAddressChange( this.usersDao.getAccount( cAddress ) );
}
@Override
@Transactional
public AccountData confirmAddressChange( EmailAddress cAddress , String code )
{
Account account = this.usersDao.getAccount( cAddress );
if ( account.getAddressChangeToken( ) != null ) {
int newId = this.usersDao.confirmAddressChange( account , code );
account = this.usersDao.getAccount( newId );
}
return this.accountToPage( account );
}
@Override
@Transactional
public void resetPreferences( EmailAddress address )
{
Account account = this.usersDao.getAccount( address );
this.prefsDao.resetPreferences( account );
}
@Override
@Transactional
public void setPreferences( EmailAddress address , Map< String , String > values )
{
Account account = this.usersDao.getAccount( address );
this.prefsDao.setPreferences( account , values );
}
@Override
@Transactional
public void setQuit( EmailAddress address , String reason )
{
Account account = this.usersDao.getAccount( address );
if ( account.getStatus( ) == AccountStatus.ACTIVE ) {
this.usersDao.setQuit( account , reason );
}
}
@Override
@Transactional
public void cancelQuit( EmailAddress address )
{
Account account = this.usersDao.getAccount( address );
if ( account.getStatus( ) == AccountStatus.QUITTING ) {
this.usersDao.cancelQuit( account );
}
}
@Override
@Transactional
public void toggleVacation( EmailAddress address )
{
Account account = this.usersDao.getAccount( address );
AccountStatus status = account.getStatus( );
if ( status == AccountStatus.ACTIVE ) {
this.usersDao.enterVacation( account );
} else if ( status == AccountStatus.START_VACATION || status == AccountStatus.VACATION ) {
this.usersDao.leaveVacation( account );
}
}
@Override
@Transactional
public List< AccountListEntry > listAccounts( AccountStatus status , boolean online )
{
if ( online ) {
return this.usersDao.listOnlineAccounts( status );
}
return this.usersDao.listAccounts( status );
}
@Override
@Transactional
public AccountViewEntry getAccountView( int id )
{
AccountViewEntry basics = this.usersDao.viewAccount( id );
if ( basics == null ) {
return null;
}
basics.setOnline( this.sessionDao.isOnline( id ) );
basics.setEmpireNames( this.namingDao.getEmpireNames( id ) );
return basics;
}
@Override
@Transactional
public AccountSessionEntry viewSessions( int id )
{
AccountViewEntry basics = this.usersDao.viewAccount( id );
if ( basics == null ) {
return null;
}
AccountSessionEntry entry = new AccountSessionEntry( basics );
entry.setSessions( this.sessionDao.getSessions( id ) );
return entry;
}
@Override
@Transactional
public void giveCredits( Administrator admin , int id , int credits )
{
this.usersDao.giveCredits( admin.getId( ) , id , credits );
}
@Override
@Transactional
public BanDetailsResponse getBanDetails( EmailAddress address )
{
ValidatedBanRequest ban = this.bansDao.getActiveBan( address );
if ( ban == null ) {
throw new RuntimeException( "account not banned" );
}
return new BanDetailsResponse( ban.getUpdate( ) , ban.getReason( ) , ban.isRedeemable( ) );
}
}

View file

@ -0,0 +1,75 @@
package com.deepclone.lw.beans.acm;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class QuitProcessorBean
implements InitializingBean , DisposableBean
{
private TransactionTemplate tTemplate;
private Ticker ticker;
private UsersDAO usersDao;
private Mailer mailer;
private QuitProcessorTask quitProcessor;
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setUsersDAO( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Autowired( required = true )
public void setMailer( Mailer mailer )
{
this.mailer = mailer;
}
@Override
public void afterPropertiesSet( )
throws Exception
{
this.quitProcessor = new QuitProcessorTask( this.tTemplate , this.usersDao , this.mailer );
this.ticker.registerTask( Frequency.MEDIUM , "Quitting accounts processor" , this.quitProcessor );
}
@Override
public void destroy( )
{
this.quitProcessor = null;
}
}

View file

@ -0,0 +1,53 @@
package com.deepclone.lw.beans.acm;
import java.util.List;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.sqld.accounts.QuittingAccount;
class QuitProcessorTask
implements Runnable
{
private TransactionTemplate tTemplate;
private UsersDAO usersDao;
private Mailer mailer;
public QuitProcessorTask( TransactionTemplate tTemplate , UsersDAO usersDao , Mailer mailer )
{
this.tTemplate = tTemplate;
this.usersDao = usersDao;
this.mailer = mailer;
}
@Override
public void run( )
{
List< QuittingAccount > quitters;
quitters = this.tTemplate.execute( new TransactionCallback< List< QuittingAccount >>( ) {
@Override
public List< QuittingAccount > doInTransaction( TransactionStatus status )
{
return usersDao.processQuits( );
}
} );
for ( QuittingAccount quitter : quitters ) {
try {
this.mailer.createMail( quitter.getLanguage( ) , "quitMail" , quitter.getAddress( ) ).queue( );
} catch ( Exception e ) {
continue;
}
}
}
}

View file

@ -0,0 +1,65 @@
package com.deepclone.lw.beans.acm;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class RequestsExpirationBean
implements InitializingBean , DisposableBean
{
private TransactionTemplate tTemplate;
private Ticker ticker;
private UsersDAO usersDao;
private RequestsExpirationTask expiration;
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setUsersDAO( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Override
public void afterPropertiesSet( )
throws Exception
{
this.expiration = new RequestsExpirationTask( this.tTemplate , this.usersDao );
this.ticker.registerTask( Frequency.MEDIUM , "Account requests expiration" , this.expiration );
}
@Override
public void destroy( )
{
this.expiration = null;
}
}

View file

@ -0,0 +1,38 @@
package com.deepclone.lw.beans.acm;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
class RequestsExpirationTask
implements Runnable
{
private TransactionTemplate tTemplate;
private UsersDAO usersDao;
public RequestsExpirationTask( TransactionTemplate tTemplate , UsersDAO usersDao )
{
this.tTemplate = tTemplate;
this.usersDao = usersDao;
}
@Override
public void run( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
usersDao.expireRequests( );
}
} );
}
}

View file

@ -0,0 +1,137 @@
package com.deepclone.lw.beans.acm;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.admin.users.SessionTerminationType;
import com.deepclone.lw.cmd.admin.users.UserSession;
import com.deepclone.lw.interfaces.acm.UserSessionDAO;
import com.deepclone.lw.utils.StoredProc;
public class UserSessionDAOBean
implements UserSessionDAO , InitializingBean
{
private SimpleJdbcTemplate dTemplate;
private final RowMapper< UserSession > mSession;
private StoredProc fSessionStart;
private StoredProc fSessionEnd;
public UserSessionDAOBean( )
{
this.mSession = new RowMapper< UserSession >( ) {
@Override
public UserSession mapRow( ResultSet rs , int rowNum )
throws SQLException
{
UserSession session = new UserSession( );
session.setId( rs.getLong( "id" ) );
session.setCredentialsId( rs.getInt( "credentials_id" ) );
session.setSessionName( rs.getString( "session" ) );
session.setClientName( rs.getString( "client_name" ) );
session.setExclusive( rs.getBoolean( "exclusive" ) );
session.setFromAddress( rs.getString( "from_address" ) );
if ( session.getFromAddress( ).startsWith( "/" )) {
session.setFromAddress( session.getFromAddress( ).substring( 1 ) );
}
session.setStarted( rs.getTimestamp( "started" ) );
session.setEnded( rs.getTimestamp( "ended" ) );
if ( session.getEnded( ) != null ) {
session.setEndType( SessionTerminationType.valueOf( rs.getString( "end_type" ) ) );
}
return session;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fSessionStart = new StoredProc( dataSource , "users" , "sessions_login" );
this.fSessionStart.addParameter( "credentials_id" , Types.INTEGER );
this.fSessionStart.addParameter( "session_name" , Types.VARCHAR );
this.fSessionStart.addParameter( "client_type" , Types.VARCHAR );
this.fSessionStart.addParameter( "ip_address" , Types.VARCHAR );
this.fSessionStart.addOutput( "s_id" , Types.BIGINT );
this.fSessionEnd = new StoredProc( dataSource , "users" , "sessions_terminate" );
this.fSessionEnd.addParameter( "session_id" , Types.BIGINT );
this.fSessionEnd.addParameter( "end_type" , "session_termination_type" );
}
@Override
public void afterPropertiesSet( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT users.sessions_server_restart()" );
}
@Override
public long startSession( int id , String sName , String client , String address )
{
return (Long) this.fSessionStart.execute( id , sName , client , address ).get( "s_id" );
}
@Override
public void endSession( long session , SessionTerminationType termination )
{
this.fSessionEnd.execute( session , termination.toString( ) );
}
@Override
public UserSession getSession( long id )
{
String sql = "SELECT * FROM users.sessions WHERE id = ?";
try {
return this.dTemplate.queryForObject( sql , this.mSession , id );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public boolean isOnline( int id )
{
String sql = "SELECT credentials_id FROM users.sessions WHERE credentials_id = ? AND end_type IS NULL AND exclusive";
try {
this.dTemplate.queryForInt( sql , id );
return true;
} catch ( EmptyResultDataAccessException e ) {
return false;
}
}
@Override
public List< UserSession > getSessions( int id )
{
String sql = "SELECT * FROM users.sessions WHERE credentials_id = ?";
return this.dTemplate.query( sql , this.mSession , id );
}
}

View file

@ -0,0 +1,550 @@
package com.deepclone.lw.beans.acm;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.admin.users.AccountBanEntry;
import com.deepclone.lw.cmd.admin.users.AccountListEntry;
import com.deepclone.lw.cmd.admin.users.AccountStatus;
import com.deepclone.lw.cmd.admin.users.AccountViewEntry;
import com.deepclone.lw.cmd.player.gdata.account.MailChangeData;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.sqld.accounts.Account;
import com.deepclone.lw.sqld.accounts.AccountOperationResult;
import com.deepclone.lw.sqld.accounts.QuittingAccount;
import com.deepclone.lw.sqld.accounts.ValidationResult;
import com.deepclone.lw.utils.EmailAddress;
import com.deepclone.lw.utils.Password;
import com.deepclone.lw.utils.StoredProc;
public class UsersDAOBean
implements UsersDAO
{
private static abstract class AccountListMapper< T extends AccountListEntry >
implements RowMapper< T >
{
protected void getCommonColumns( AccountListEntry e , ResultSet rs )
throws SQLException
{
e.setId( rs.getInt( "id" ) );
e.setAddress( rs.getString( "address" ) );
e.setLanguage( rs.getString( "language" ) );
e.setStatus( AccountStatus.valueOf( rs.getString( "status" ) ) );
e.setCurrentEmpire( rs.getString( "current_empire" ) );
}
}
private final RowMapper< Account > accountMapper;
private final RowMapper< QuittingAccount > quitMapper;
private final RowMapper< MailChangeData > mailChangeMapper;
private final AccountListMapper< AccountListEntry > mAccountList;
private final AccountListMapper< AccountViewEntry > mAccountView;
private SimpleJdbcTemplate dTemplate;
private StoredProc fCreateAccount;
private StoredProc fMailFailure;
private StoredProc fValidate;
private StoredProc fReactivate;
private StoredProc fRequestPasswordRecovery;
private StoredProc fCancelPasswordRecovery;
private StoredProc fConfirmPasswordRecovery;
private StoredProc fSetLanguage;
private StoredProc fSetPassword;
private StoredProc fSetAddress;
private StoredProc fCancelAddressChange;
private StoredProc fConfirmAddressChange;
private StoredProc fSetQuit;
private StoredProc fCancelQuit;
private StoredProc fEnterVacation;
private StoredProc fLeaveVacation;
private StoredProc fGrantCredits;
public UsersDAOBean( )
{
this.accountMapper = new RowMapper< Account >( ) {
@Override
public Account mapRow( ResultSet rs , int rowNum )
throws SQLException
{
Account account = new Account( );
account.setId( rs.getInt( "id" ) );
account.setAddress( rs.getString( "address" ) );
account.setLanguage( rs.getString( "language" ) );
account.setPassMd5( rs.getString( "pass_md5" ) );
account.setPassSha1( rs.getString( "pass_sha1" ) );
account.setGameCredits( rs.getInt( "game_credits" ) );
account.setStatus( AccountStatus.valueOf( rs.getString( "status" ) ) );
account.setValidationToken( rs.getString( "validation_token" ) );
account.setPwdRecoveryToken( rs.getString( "pwd_recovery_token" ) );
account.setAddressChangeToken( rs.getString( "address_change_token" ) );
account.setNewAddress( rs.getString( "new_address" ) );
account.setVacationCredits( rs.getInt( "vacation_credits" ) );
account.setVacationTime( rs.getInt( "vacation_time" ) );
account.setVacationStart( rs.getTimestamp( "vacation_start" ) );
account.setInactivityStart( rs.getTimestamp( "inactivity_begin" ) );
account.setInactivityReason( rs.getString( "inactivity_reason" ) );
account.setBanRequestId( rs.getInt( "ban_request_id" ) );
return account;
}
};
this.mailChangeMapper = new RowMapper< MailChangeData >( ) {
@Override
public MailChangeData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
if ( rs.getBoolean( "used" ) ) {
return new MailChangeData( rs.getTimestamp( "expires" ) );
}
return new MailChangeData( rs.getTimestamp( "expires" ) , rs.getString( "new_address" ) );
}
};
this.quitMapper = new RowMapper< QuittingAccount >( ) {
@Override
public QuittingAccount mapRow( ResultSet rs , int rowNum )
throws SQLException
{
QuittingAccount acc = new QuittingAccount( );
acc.setId( rs.getInt( "id" ) );
acc.setAddress( rs.getString( "address" ) );
acc.setLanguage( rs.getString( "language" ) );
return acc;
}
};
this.mAccountList = new AccountListMapper< AccountListEntry >( ) {
@Override
public AccountListEntry mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AccountListEntry e = new AccountListEntry( );
this.getCommonColumns( e , rs );
return e;
}
};
this.mAccountView = new AccountListMapper< AccountViewEntry >( ) {
@Override
public AccountViewEntry mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AccountViewEntry e = new AccountViewEntry( );
this.getCommonColumns( e , rs );
e.setGameCredits( rs.getInt( "game_credits" ) );
e.setVacationCredits( rs.getInt( "vacation_credits" ) );
if ( !e.getStatus( ).isActive( ) && e.getStatus( ) != AccountStatus.UNCONFIRMED ) {
e.setStatusStart( rs.getTimestamp( "inactivity_begin" ) );
} else {
e.setStatusStart( rs.getTimestamp( "vacation_start" ) );
}
e.setInactivityReason( rs.getString( "inactivity_reason" ) );
e.setEmpireId( (Integer) rs.getObject( "current_empire_id" ) );
if ( e.getStatus( ) == AccountStatus.BANNED ) {
AccountBanEntry ban = new AccountBanEntry( );
ban.setRequestedById( rs.getInt( "ban_req_id" ) );
ban.setRequestedByName( rs.getString( "ban_req_name" ) );
ban.setConfirmedById( rs.getInt( "ban_val_id" ) );
ban.setConfirmedByName( rs.getString( "ban_val_name" ) );
e.setBan( ban );
}
e.setWarnings( rs.getInt( "warnings_count" ) );
e.setLastWarning( rs.getTimestamp( "warnings_last" ) );
return e;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fCreateAccount = new StoredProc( dataSource , "users" , "create_credentials" );
this.fCreateAccount.addParameter( "address" , Types.VARCHAR );
this.fCreateAccount.addParameter( "lang_id" , Types.VARCHAR );
this.fCreateAccount.addParameter( "pass_md5" , Types.VARCHAR );
this.fCreateAccount.addParameter( "pass_sha1" , Types.VARCHAR );
this.fCreateAccount.addOutput( "err_code" , Types.INTEGER );
this.fCreateAccount.addOutput( "a_id" , Types.INTEGER );
this.fMailFailure = new StoredProc( dataSource , "users" , "validation_mail_failure" );
this.fMailFailure.addParameter( "a_id" , Types.INTEGER );
this.fValidate = new StoredProc( dataSource , "users" , "validate" );
this.fValidate.addParameter( "addr" , Types.VARCHAR );
this.fValidate.addParameter( "vtoken" , Types.VARCHAR );
this.fValidate.addParameter( "empname" , Types.VARCHAR );
this.fValidate.addParameter( "plname" , Types.VARCHAR );
this.fValidate.addOutput( "account_error" , Types.INTEGER );
this.fValidate.addOutput( "empire_error" , Types.INTEGER );
this.fValidate.addOutput( "planet_error" , Types.INTEGER );
this.fReactivate = new StoredProc( dataSource , "users" , "reactivate" );
this.fReactivate.addParameter( "addr" , Types.VARCHAR );
this.fReactivate.addOutput( "success" , Types.BOOLEAN );
this.fReactivate.addOutput( "a_id" , Types.INTEGER );
this.fRequestPasswordRecovery = new StoredProc( dataSource , "users" , "request_password_recovery" );
this.fRequestPasswordRecovery.addParameter( "addr" , Types.VARCHAR );
this.fRequestPasswordRecovery.addOutput( "err_code" , Types.INTEGER );
this.fRequestPasswordRecovery.addOutput( "a_id" , Types.INTEGER );
this.fCancelPasswordRecovery = new StoredProc( dataSource , "users" , "cancel_password_recovery" );
this.fCancelPasswordRecovery.addParameter( "a_id" , Types.INTEGER );
this.fConfirmPasswordRecovery = new StoredProc( dataSource , "users" , "confirm_password_recovery" );
this.fConfirmPasswordRecovery.addParameter( "umail" , Types.VARCHAR );
this.fConfirmPasswordRecovery.addParameter( "tok" , Types.VARCHAR );
this.fConfirmPasswordRecovery.addParameter( "pmd5" , Types.VARCHAR );
this.fConfirmPasswordRecovery.addParameter( "psha1" , Types.VARCHAR );
this.fConfirmPasswordRecovery.addOutput( "err_code" , Types.INTEGER );
this.fConfirmPasswordRecovery.addOutput( "a_id" , Types.INTEGER );
this.fSetLanguage = new StoredProc( dataSource , "users" , "set_language" );
this.fSetLanguage.addParameter( "umail" , Types.VARCHAR );
this.fSetLanguage.addParameter( "lang_id" , Types.VARCHAR );
this.fSetPassword = new StoredProc( dataSource , "users" , "set_password" );
this.fSetPassword.addParameter( "u_id" , Types.INTEGER );
this.fSetPassword.addParameter( "pmd5" , Types.VARCHAR );
this.fSetPassword.addParameter( "psha1" , Types.VARCHAR );
this.fSetPassword.addOutput( "success" , Types.BOOLEAN );
this.fSetAddress = new StoredProc( dataSource , "users" , "request_address_change" );
this.fSetAddress.addParameter( "u_id" , Types.INTEGER );
this.fSetAddress.addParameter( "n_address" , Types.VARCHAR );
this.fSetAddress.addOutput( "err_code" , Types.INTEGER );
this.fCancelAddressChange = new StoredProc( dataSource , "users" , "cancel_address_change" );
this.fCancelAddressChange.addParameter( "u_id" , Types.INTEGER );
this.fConfirmAddressChange = new StoredProc( dataSource , "users" , "confirm_address_change" );
this.fConfirmAddressChange.addParameter( "u_id" , Types.INTEGER );
this.fConfirmAddressChange.addParameter( "token" , Types.VARCHAR );
this.fConfirmAddressChange.addOutput( "n_id" , Types.INTEGER );
this.fSetQuit = new StoredProc( dataSource , "users" , "set_account_quit" );
this.fSetQuit.addParameter( "accound_id" , Types.INTEGER );
this.fSetQuit.addParameter( "reason_text" , Types.VARCHAR );
this.fCancelQuit = new StoredProc( dataSource , "users" , "cancel_account_quit" );
this.fCancelQuit.addParameter( "account_id" , Types.INTEGER );
this.fEnterVacation = new StoredProc( dataSource , "users" , "set_vacation" );
this.fEnterVacation.addParameter( "account_id" , Types.INTEGER );
this.fLeaveVacation = new StoredProc( dataSource , "users" , "leave_vacation" );
this.fLeaveVacation.addParameter( "account_id" , Types.INTEGER );
this.fGrantCredits = new StoredProc( dataSource , "admin" , "grant_user_credits" );
this.fGrantCredits.addParameter( "admin_id" , Types.INTEGER );
this.fGrantCredits.addParameter( "account_id" , Types.INTEGER );
this.fGrantCredits.addParameter( "credits" , Types.INTEGER );
}
@Override
public Account getAccount( EmailAddress address )
{
String sql = "SELECT * FROM users.accounts_view WHERE address = ?";
try {
return this.dTemplate.queryForObject( sql , this.accountMapper , address.getAddress( ) );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public Account getAccount( int id )
{
String sql = "SELECT * FROM users.accounts_view WHERE id = ?";
try {
return this.dTemplate.queryForObject( sql , this.accountMapper , id );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
private AccountOperationResult mapToResult( Map< String , Object > m )
{
int errCode = (Integer) m.get( "err_code" );
AccountOperationResult result = new AccountOperationResult( );
result.setErrorCode( errCode );
if ( errCode == 0 ) {
result.setAccount( this.getAccount( (Integer) m.get( "a_id" ) ) );
}
return result;
}
@Override
public AccountOperationResult createAccount( EmailAddress address , Password password , String language )
{
Map< String , Object > m = this.fCreateAccount.execute( address.getAddress( ) , language , password.getMd5( ) ,
password.getSha1( ) );
return this.mapToResult( m );
}
@Override
public void cancelAccountValidation( Account account )
{
this.fMailFailure.execute( account.getId( ) );
}
@Override
public ValidationResult validateAccount( EmailAddress address , String token , String eName , String pName )
{
Map< String , Object > m = this.fValidate.execute( address.getAddress( ) , token , eName , pName );
ValidationResult vr = new ValidationResult( );
vr.setAccountError( (Integer) m.get( "account_error" ) );
vr.setEmpireError( (Integer) m.get( "empire_error" ) );
vr.setPlanetError( (Integer) m.get( "planet_error" ) );
return vr;
}
@Override
public Account reactivateAccount( EmailAddress address )
{
Map< String , Object > m = this.fReactivate.execute( address.getAddress( ) );
boolean success = (Boolean) m.get( "success" );
if ( !success ) {
return null;
}
return this.getAccount( (Integer) m.get( "a_id" ) );
}
@Override
public AccountOperationResult requestPasswordRecovery( EmailAddress address )
{
Map< String , Object > m = this.fRequestPasswordRecovery.execute( address.getAddress( ) );
return this.mapToResult( m );
}
@Override
public void cancelPasswordRecovery( Account account )
{
this.fCancelPasswordRecovery.execute( account.getId( ) );
}
@Override
public AccountOperationResult confirmPasswordRecovery( EmailAddress address , String token , Password nPassword )
{
Map< String , Object > m = this.fConfirmPasswordRecovery.execute( address.getAddress( ) , token , nPassword
.getMd5( ) , nPassword.getSha1( ) );
return this.mapToResult( m );
}
@Override
public MailChangeData getMailChange( int accountId )
{
String sql = "SELECT * FROM users.mail_change_view WHERE id = ?";
try {
return this.dTemplate.queryForObject( sql , this.mailChangeMapper , accountId );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public void setLanguage( EmailAddress address , String language )
{
this.fSetLanguage.execute( address.getAddress( ) , language );
}
@Override
public boolean setPassword( Account account , Password newPassword )
{
int id = account.getId( );
String sha1 = newPassword.getSha1( );
String md5 = newPassword.getMd5( );
return (Boolean) this.fSetPassword.execute( id , sha1 , md5 ).get( "success" );
}
@Override
public int setAddress( Account account , EmailAddress nAddress )
{
return (Integer) this.fSetAddress.execute( account.getId( ) , nAddress.getAddress( ) ).get( "err_code" );
}
@Override
public void cancelAddressChange( Account account )
{
this.fCancelAddressChange.execute( account.getId( ) );
}
@Override
public int confirmAddressChange( Account account , String code )
{
Integer nv;
nv = (Integer) this.fConfirmAddressChange.execute( account.getId( ) , code ).get( "n_id" );
return ( nv == null ) ? account.getId( ) : nv.intValue( );
}
@Override
public void expireRequests( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT users.expire_requests( )" );
}
@Override
public void setQuit( Account account , String reason )
{
this.fSetQuit.execute( account.getId( ) , reason );
}
@Override
public void cancelQuit( Account account )
{
this.fCancelQuit.execute( account.getId( ) );
}
@Override
public List< QuittingAccount > processQuits( )
{
String sql = "SELECT * FROM users.process_quit_requests( )";
return this.dTemplate.query( sql , this.quitMapper );
}
@Override
public void enterVacation( Account account )
{
this.fEnterVacation.execute( account.getId( ) );
}
@Override
public void leaveVacation( Account account )
{
this.fLeaveVacation.execute( account.getId( ) );
}
@Override
public void processVacations( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT users.process_vacations( )" );
}
@Override
public List< AccountListEntry > listAccounts( AccountStatus status )
{
String sql = "SELECT * FROM admin.users_list";
Object[] params;
if ( status != null ) {
sql += " WHERE status = ?";
params = new Object[] {
status.toString( )
};
} else {
params = new Object[] { };
}
return this.dTemplate.query( sql , this.mAccountList , params );
}
@Override
public List< AccountListEntry > listOnlineAccounts( AccountStatus status )
{
String sql = "SELECT u.* FROM admin.users_list u INNER JOIN users.sessions s ON s.credentials_id = u.id AND s.end_type IS NULL AND s.exclusive";
Object[] params;
if ( status != null ) {
sql += " WHERE u.status = ?";
params = new Object[] {
status.toString( )
};
} else {
params = new Object[] { };
}
return this.dTemplate.query( sql , this.mAccountList , params );
}
@Override
public AccountViewEntry viewAccount( int id )
{
String sql = "SELECT * FROM admin.users_list WHERE id = ?";
try {
return this.dTemplate.queryForObject( sql , this.mAccountView , id );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public void giveCredits( int adminId , int accountId , int credits )
{
this.fGrantCredits.execute( adminId , accountId , credits );
}
@Override
public void deleteOldAccounts( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT users.delete_old_accounts( )" );
}
@Override
public List< QuittingAccount > getInactivesToWarn( )
{
String sql = "SELECT * FROM users.check_inactivity_emails( )";
return this.dTemplate.query( sql , this.quitMapper );
}
@Override
public List< QuittingAccount > getInactivesToDisable( )
{
String sql = "SELECT * FROM users.check_inactivity( )";
return this.dTemplate.query( sql , this.quitMapper );
}
}

View file

@ -0,0 +1,65 @@
package com.deepclone.lw.beans.acm;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class VacationProcessorBean
implements InitializingBean , DisposableBean
{
private TransactionTemplate tTemplate;
private Ticker ticker;
private UsersDAO usersDao;
private VacationProcessorTask vacationProcessor;
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setUsersDAO( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Override
public void afterPropertiesSet( )
throws Exception
{
this.vacationProcessor = new VacationProcessorTask( this.tTemplate , this.usersDao );
this.ticker.registerTask( Frequency.MINUTE , "Vacation processor" , this.vacationProcessor );
}
@Override
public void destroy( )
{
this.vacationProcessor = null;
}
}

View file

@ -0,0 +1,38 @@
package com.deepclone.lw.beans.acm;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.acm.UsersDAO;
class VacationProcessorTask
implements Runnable
{
private TransactionTemplate tTemplate;
private UsersDAO usersDao;
public VacationProcessorTask( TransactionTemplate tTemplate , UsersDAO usersDao )
{
this.tTemplate = tTemplate;
this.usersDao = usersDao;
}
@Override
public void run( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
usersDao.processVacations( );
}
} );
}
}

View file

@ -0,0 +1,251 @@
package com.deepclone.lw.beans.admin;
import java.net.InetAddress;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.admin.adata.AdminOverview;
import com.deepclone.lw.interfaces.admin.AdminDAO;
import com.deepclone.lw.interfaces.admin.AdminDAOException;
import com.deepclone.lw.sqld.admin.AdminConnection;
import com.deepclone.lw.sqld.admin.AdminRecord;
import com.deepclone.lw.utils.EmailAddress;
import com.deepclone.lw.utils.StoredProc;
public class AdminDAOBean
implements AdminDAO
{
private static final String sGetAdminById = "SELECT * FROM admin.admins_view WHERE administrator_id = ?";
private static final String sGetAdminByAddress = "SELECT * FROM admin.admins_view WHERE address = ?";
private static final String sGetAdminByName = "SELECT * FROM admin.admins_view WHERE lower( name ) = ?";
private static final String sListAdministrators = "SELECT * FROM admin.admins_view ORDER BY active DESC , name";
private SimpleJdbcTemplate dTemplate;
private final RowMapper< AdminRecord > mAdminRecord;
private final RowMapper< AdminOverview > mAdminOverview;
private StoredProc fCreateAdmin;
private StoredProc fLogConnection;
private StoredProc fLogDisconnection;
private StoredProc fSetPassword;
private StoredProc fResetPassword;
private StoredProc fSetPrivileges;
public AdminDAOBean( )
{
this.mAdminRecord = new RowMapper< AdminRecord >( ) {
@Override
public AdminRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AdminRecord admin = new AdminRecord( );
admin.setId( rs.getInt( "administrator_id" ) );
admin.setName( rs.getString( "name" ) );
admin.setPrivileges( rs.getInt( "privileges" ) );
admin.setActive( rs.getBoolean( "active" ) );
admin.setAccount( (Integer) rs.getObject( "account_id" ) );
admin.setAddress( rs.getString( "address" ) );
admin.setpMd5( rs.getString( "pass_md5" ) );
admin.setpSha1( rs.getString( "pass_sha1" ) );
admin.setPassChangeRequired( (Boolean) rs.getObject( "pass_change_required" ) );
return admin;
}
};
this.mAdminOverview = new RowMapper< AdminOverview >( ) {
@Override
public AdminOverview mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AdminOverview ov = new AdminOverview( );
ov.setId( rs.getInt( "admin_id" ) );
ov.setNewMessages( rs.getLong( "new_messages" ) );
ov.setPendingNames( rs.getLong( "pending_names" ) );
ov.setPendingBans( rs.getLong( "pending_bans" ) );
ov.setPendingBugs( rs.getLong( "pending_bugs" ) );
ov.setOpenBugs( rs.getLong( "open_bugs" ) );
ov.setUpdatedBugs( rs.getLong( "updated_bugs" ) );
return ov;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fCreateAdmin = new StoredProc( dataSource , "admin" , "create_admin" );
this.fCreateAdmin.addParameter( "address" , Types.VARCHAR );
this.fCreateAdmin.addParameter( "admin_name" , Types.VARCHAR );
this.fCreateAdmin.addParameter( "privileges" , Types.INTEGER );
this.fCreateAdmin.addOutput( "err_code" , Types.INTEGER );
this.fCreateAdmin.addOutput( "admin_id" , Types.INTEGER );
this.fLogConnection = new StoredProc( dataSource , "admin" , "log_connection" );
this.fLogConnection.addParameter( "admin_id" , Types.INTEGER );
this.fLogConnection.addParameter( "result" , "admin_connection_result" );
this.fLogConnection.addParameter( "ip_address" , Types.VARCHAR );
this.fLogDisconnection = new StoredProc( dataSource , "admin" , "log_disconnection" );
this.fLogDisconnection.addParameter( "admin_id" , Types.INTEGER );
this.fSetPassword = new StoredProc( dataSource , "admin" , "set_password" );
this.fSetPassword.addParameter( "admin_id" , Types.INTEGER );
this.fSetPassword.addParameter( "pass_sha1" , Types.VARCHAR );
this.fSetPassword.addParameter( "pass_md5" , Types.VARCHAR );
this.fSetPassword.addOutput( "success" , Types.BOOLEAN );
this.fResetPassword = new StoredProc( dataSource , "admin" , "reset_password" );
this.fResetPassword.addParameter( "admin_id" , Types.INTEGER );
this.fResetPassword.addParameter( "superuser_id" , Types.INTEGER );
this.fResetPassword.addOutput( "success" , Types.BOOLEAN );
this.fSetPrivileges = new StoredProc( dataSource , "admin" , "set_privileges" );
this.fSetPrivileges.addParameter( "admin_id" , Types.INTEGER );
this.fSetPrivileges.addParameter( "superuser_id" , Types.INTEGER );
this.fSetPrivileges.addParameter( "privileges" , Types.INTEGER );
this.fSetPrivileges.addOutput( "success" , Types.BOOLEAN );
}
@Override
public AdminRecord getAdmin( int id )
{
try {
return this.dTemplate.queryForObject( sGetAdminById , this.mAdminRecord , id );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public AdminRecord getAdmin( EmailAddress address )
{
try {
return this.dTemplate.queryForObject( sGetAdminByAddress , this.mAdminRecord , address.getAddress( ) );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public AdminRecord getAdmin( String name )
{
try {
return this.dTemplate.queryForObject( sGetAdminByName , this.mAdminRecord , name.toLowerCase( ) );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public int createAdmin( String address , String name , int privileges )
throws AdminDAOException
{
Map< String , Object > result = this.fCreateAdmin.execute( address , name , privileges );
int errCode = (Integer) result.get( "err_code" );
if ( errCode != 0 ) {
throw new AdminDAOException( errCode );
}
return (Integer) result.get( "admin_id" );
}
@Override
public void logConnectionAttempt( int id , AdminConnection status , InetAddress address )
{
this.fLogConnection.execute( id , status.toString( ) , address.getHostAddress( ) );
}
@Override
public void logDisconnection( int id )
{
this.fLogDisconnection.execute( id );
}
@Override
public boolean setPassword( int id , String sha1 , String md5 )
{
return (Boolean) this.fSetPassword.execute( id , sha1 , md5 ).get( "success" );
}
@Override
public List< AdminRecord > listAdministrators( )
{
return this.dTemplate.query( sListAdministrators , this.mAdminRecord );
}
@Override
public boolean resetPassword( int identifier , int superuser )
{
return (Boolean) this.fResetPassword.execute( identifier , superuser ).get( "success" );
}
@Override
public boolean setPrivileges( int identifier , int superuser , int privileges )
{
return (Boolean) this.fSetPrivileges.execute( identifier , superuser , privileges ).get( "success" );
}
@Override
public AdminOverview getOverview( int id )
{
String sql = "SELECT * FROM admin.overview WHERE admin_id = ?";
try {
return this.dTemplate.queryForObject( sql , this.mAdminOverview , id );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public List< AdminOverview > getOverviews( )
{
String sql = "SELECT * FROM admin.overview";
return this.dTemplate.query( sql , this.mAdminOverview );
}
@Override
public Timestamp isRecapTime( )
{
String sql = "SELECT * FROM admin.is_recap_time( )";
RowMapper< Timestamp > mapper = new RowMapper< Timestamp >( ) {
@Override
public Timestamp mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return rs.getTimestamp( 1 );
}
};
return this.dTemplate.queryForObject( sql , mapper );
}
}

View file

@ -0,0 +1,78 @@
package com.deepclone.lw.beans.admin;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.admin.AdminDAO;
import com.deepclone.lw.interfaces.eventlog.LogReader;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class AdminRecapBean
implements InitializingBean , DisposableBean
{
private AdminRecapTask task;
private TransactionTemplate tTemplate;
private Ticker ticker;
private Mailer mailer;
private AdminDAO adminDao;
private LogReader logReader;
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setMailer( Mailer mailer )
{
this.mailer = mailer;
}
@Autowired( required = true )
public void setAdminDao( AdminDAO adminDao )
{
this.adminDao = adminDao;
}
@Autowired( required = true )
public void setLogReader( LogReader logReader )
{
this.logReader = logReader;
}
@Override
public void afterPropertiesSet( )
{
this.task = new AdminRecapTask( this.tTemplate , this.mailer , this.adminDao , this.logReader );
this.ticker.registerTask( Frequency.LOW , "Admin recap task" , this.task );
}
@Override
public void destroy( )
{
this.task = null;
}
}

View file

@ -0,0 +1,162 @@
package com.deepclone.lw.beans.admin;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.cmd.admin.adata.AdminOverview;
import com.deepclone.lw.cmd.admin.adata.Privileges;
import com.deepclone.lw.cmd.admin.logs.LogEntry;
import com.deepclone.lw.interfaces.admin.AdminDAO;
import com.deepclone.lw.interfaces.eventlog.LogReader;
import com.deepclone.lw.interfaces.mailer.MailData;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.sqld.admin.AdminRecord;
public class AdminRecapTask
implements Runnable
{
private final TransactionTemplate tTemplate;
private final Mailer mailer;
private final AdminDAO adminDao;
private final LogReader logReader;
private Timestamp isTime;
private List< AdminRecord > admins;
private final Map< Integer , AdminOverview > overviews = new HashMap< Integer , AdminOverview >( );
private List< LogEntry > logs;
public AdminRecapTask( TransactionTemplate tTemplate , Mailer mailer , AdminDAO adminDao , LogReader logReader )
{
this.tTemplate = tTemplate;
this.mailer = mailer;
this.adminDao = adminDao;
this.logReader = logReader;
}
@Override
public void run( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
checkRecap( );
}
} );
if ( this.isTime == null ) {
return;
}
String logs = this.buildLogsString( );
for ( AdminRecord admin : this.admins ) {
if ( !admin.isActive( ) ) {
continue;
}
String mailContents = this.buildMailContents( admin , logs );
if ( "".equals( mailContents ) ) {
continue;
}
MailData mail;
try {
mail = this.mailer.createMail( "en" , "adminRecapMail" , admin.getAddress( ) );
mail.setData( "contents" , mailContents );
mail.queue( );
} catch ( Exception e ) {
continue;
}
}
}
private String buildMailContents( AdminRecord admin , String logs )
{
AdminOverview overview = this.overviews.get( admin.getId( ) );
if ( overview == null ) {
return "";
}
StringBuilder mail = new StringBuilder( );
if ( overview.getNewMessages( ) > 0 ) {
mail.append( "Unread messages: " ).append( overview.getNewMessages( ) ).append( "\n" );
}
int privs = admin.getPrivileges( );
if ( Privileges.NAME.hasPrivilege( privs ) && overview.getPendingNames( ) > 0 ) {
mail.append( "Unvalidated map names: " ).append( overview.getPendingNames( ) ).append( "\n" );
}
if ( Privileges.BANH.hasPrivilege( privs ) && overview.getPendingBans( ) > 0 ) {
mail.append( "Pending ban requests: " ).append( overview.getPendingBans( ) ).append( "\n" );
}
if ( Privileges.BUGT.hasPrivilege( privs ) ) {
boolean showBugs = false;
if ( overview.getPendingBugs( ) > 0 ) {
mail.append( "Bug reports pending validation: " ).append( overview.getPendingBugs( ) ).append( "\n" );
showBugs = true;
}
if ( overview.getUpdatedBugs( ) > 0 ) {
mail.append( "Updated bug reports: " ).append( overview.getUpdatedBugs( ) ).append( "\n" );
showBugs = true;
}
if ( showBugs && overview.getOpenBugs( ) > 0 ) {
mail.append( "Open bug reports: " ).append( overview.getOpenBugs( ) ).append( "\n" );
}
}
if ( !"".equals( logs ) && Privileges.LOGS.hasPrivilege( privs ) ) {
mail.append( "\n" ).append( logs );
}
return mail.toString( );
}
private String buildLogsString( )
{
if ( this.logs.isEmpty( ) ) {
return "";
}
StringBuilder builder = new StringBuilder( ).append( "Administrative actions log\n\n" );
SimpleDateFormat dfmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
for ( LogEntry entry : this.logs ) {
builder.append( dfmt.format( entry.getTimestamp( ) ) );
builder.append( " - " ).append( entry.getLevel( ).toString( ) );
builder.append( " - " ).append( entry.getAbout( ) );
builder.append( " - " ).append( entry.getEntry( ) );
builder.append( "\n" );
}
return builder.toString( );
}
private void checkRecap( )
{
this.isTime = this.adminDao.isRecapTime( );
if ( this.isTime == null ) {
return;
}
this.admins = this.adminDao.listAdministrators( );
for ( AdminOverview ov : this.adminDao.getOverviews( ) ) {
this.overviews.put( ov.getId( ) , ov );
}
this.logs = this.logReader.getAdminLogSince( this.isTime );
}
}

View file

@ -0,0 +1,356 @@
package com.deepclone.lw.beans.admin;
import java.net.InetAddress;
import java.util.List;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.ObjectNameError;
import com.deepclone.lw.cmd.admin.AdminOverviewResponse;
import com.deepclone.lw.cmd.admin.adata.AdminOverview;
import com.deepclone.lw.cmd.admin.adata.Administrator;
import com.deepclone.lw.cmd.admin.adata.Privileges;
import com.deepclone.lw.cmd.admin.bans.BanRequest;
import com.deepclone.lw.cmd.admin.bans.BanType;
import com.deepclone.lw.cmd.admin.bans.BansSummaryResponse;
import com.deepclone.lw.cmd.admin.bans.ListBansResponse;
import com.deepclone.lw.cmd.admin.bans.RequestBanResponse;
import com.deepclone.lw.cmd.admin.logs.LogLevel;
import com.deepclone.lw.cmd.admin.su.AddAdministratorResponse;
import com.deepclone.lw.cmd.admin.su.AddAdministratorResponse.AddressError;
import com.deepclone.lw.interfaces.acm.PasswordProhibitedException;
import com.deepclone.lw.interfaces.admin.AdminDAO;
import com.deepclone.lw.interfaces.admin.AdminDAOException;
import com.deepclone.lw.interfaces.admin.Administration;
import com.deepclone.lw.interfaces.admin.BanMailData;
import com.deepclone.lw.interfaces.admin.BansDAO;
import com.deepclone.lw.interfaces.admin.IpBan;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
import com.deepclone.lw.interfaces.mailer.MailData;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.sqld.admin.AdminConnection;
import com.deepclone.lw.sqld.admin.AdminRecord;
import com.deepclone.lw.utils.DigestHelper;
import com.deepclone.lw.utils.EmailAddress;
import com.deepclone.lw.utils.Password;
@Transactional
public class AdministrationBean
implements Administration
{
private SystemLogger sysLog;
private AdminDAO adminDao;
private IpBan ipBan;
private BansDAO bansDao;
private Mailer mailer;
@Autowired( required = true )
public void setLogger( Logger logger )
{
this.sysLog = logger.getSystemLogger( "Administration" );
}
@Autowired( required = true )
public void setAdminDao( AdminDAO adminDao )
{
this.adminDao = adminDao;
}
@Autowired( required = true )
public void setIpBan( IpBan ipBan )
{
this.ipBan = ipBan;
}
@Autowired( required = true )
public void setBansDao( BansDAO bansDao )
{
this.bansDao = bansDao;
}
@Autowired( required = true )
public void setMailer( Mailer mailer )
{
this.mailer = mailer;
}
@Override
public AdminRecord getAdmin( int id )
{
return this.adminDao.getAdmin( id );
}
@Override
public AdminRecord login( EmailAddress address , String challenge , String sha1Hash , String md5Hash ,
InetAddress ipAddress )
{
// Check IP ban
if ( this.ipBan.isBanned( ipAddress ) ) {
return null;
}
// Find admin record
AdminRecord record = this.adminDao.getAdmin( address );
if ( record == null ) {
this.ipBan.increaseBanCounter( ipAddress );
this.sysLog.log( LogLevel.WARNING ,
"failed login attempt from unknown address '" + address.getAddress( ) + "'" ).flush( );
return null;
}
// Make sure the administrator is active
if ( !record.isActive( ) ) {
this.ipBan.increaseBanCounter( ipAddress );
this.adminDao.logConnectionAttempt( record.getId( ) , AdminConnection.INACTIVE , ipAddress );
return null;
}
// Check password
String eSha1 = DigestHelper.digest( "sha-1" , challenge + " " + record.getpSha1( ) );
String eMd5 = DigestHelper.digest( "md5" , challenge + " " + record.getpMd5( ) );
if ( eSha1.equals( sha1Hash ) && eMd5.equals( md5Hash ) ) {
this.adminDao.logConnectionAttempt( record.getId( ) , AdminConnection.SUCCESS , ipAddress );
return record;
}
this.ipBan.increaseBanCounter( ipAddress );
this.adminDao.logConnectionAttempt( record.getId( ) , AdminConnection.PASSWORD , ipAddress );
return null;
}
@Override
public void logout( int adminId )
{
this.adminDao.logDisconnection( adminId );
}
@Override
public boolean setPassword( int id , String challenge , String sha1Auth , String md5Auth , Password password )
throws PasswordProhibitedException
{
AdminRecord admin = this.getAdmin( id );
// Check challenge response
String eSha1 = DigestHelper.digest( "sha-1" , challenge + " " + admin.getpSha1( ) );
String eMd5 = DigestHelper.digest( "md5" , challenge + " " + admin.getpMd5( ) );
if ( ! ( eSha1.equals( sha1Auth ) && eMd5.equals( md5Auth ) ) ) {
return false;
}
// Try setting the password
if ( !this.adminDao.setPassword( id , password.getSha1( ) , password.getMd5( ) ) ) {
throw new PasswordProhibitedException( );
}
return true;
}
@Override
public List< AdminRecord > listAdministrators( )
{
return this.adminDao.listAdministrators( );
}
@Override
public AddAdministratorResponse createAdmin( Administrator creator , String address , String name , int privileges )
{
int errCode;
try {
this.adminDao.createAdmin( address , name , privileges );
return new AddAdministratorResponse( creator , false );
} catch ( AdminDAOException e ) {
errCode = e.getErrorCode( );
}
AddressError aError;
ObjectNameError nError;
switch ( errCode ) {
case 1:
aError = AddressError.NOT_FOUND;
nError = null;
break;
case 2:
aError = AddressError.STATUS;
nError = null;
break;
case 3:
aError = null;
nError = ObjectNameError.UNAVAILABLE;
break;
case 4:
aError = AddressError.ALREADY_ADMIN;
nError = null;
break;
default:
throw new RuntimeException( "unknown error code " + errCode );
}
return new AddAdministratorResponse( creator , aError , address , nError , name , false , privileges );
}
@Override
public AdminRecord resetPassword( Administrator admin , int identifier )
{
if ( this.adminDao.resetPassword( identifier , admin.getId( ) ) ) {
return this.adminDao.getAdmin( identifier );
}
return null;
}
@Override
public AdminRecord setPrivileges( Administrator admin , int identifier , Set< Privileges > privileges )
{
int privs = 0;
for ( Privileges p : privileges ) {
privs = p.grant( privs );
}
if ( this.adminDao.setPrivileges( identifier , admin.getId( ) , privs ) ) {
return this.adminDao.getAdmin( identifier );
}
return null;
}
@Override
public BansSummaryResponse getBansSummary( Administrator admin )
{
return new BansSummaryResponse( admin , this.bansDao.getSummary( ) );
}
@Override
public ListBansResponse getBans( Administrator admin , BanType type )
{
List< BanRequest > bans;
switch ( type ) {
case PENDING:
bans = this.bansDao.getPending( );
break;
case ARCHIVED:
bans = this.bansDao.getArchived( );
break;
case VALIDATED:
bans = this.bansDao.getActive( );
break;
default:
throw new RuntimeException( "unknown ban type " + type );
}
return new ListBansResponse( admin , type , bans );
}
@Override
public RequestBanResponse requestBan( Administrator admin , String user , boolean empire , String reason )
{
int errCode;
if ( empire ) {
errCode = this.bansDao.requestBan( admin.getId( ) , user , reason );
} else {
EmailAddress address = new EmailAddress( user );
if ( !address.isValid( ) ) {
errCode = 1;
} else {
errCode = this.bansDao.requestBan( admin.getId( ) , address , reason );
}
}
if ( errCode == 0 ) {
return new RequestBanResponse( admin , false );
}
RequestBanResponse.Error error;
switch ( errCode ) {
case 1:
error = RequestBanResponse.Error.NOT_FOUND;
break;
case 2:
error = RequestBanResponse.Error.BANNED;
break;
default:
throw new RuntimeException( "unknown error code " + errCode );
}
return new RequestBanResponse( admin , error , user , empire , reason );
}
@Override
public void rejectBan( Administrator admin , int id , String reason )
{
this.bansDao.rejectBan( admin.getId( ) , id , reason );
}
@Override
public void confirmBan( Administrator admin , int id )
{
BanMailData result = this.bansDao.validateBan( admin.getId( ) , id );
if ( result == null ) {
return;
}
try {
MailData mail = this.mailer.createMail( result.language , "bannedMail" , result.address );
mail.setData( "reason" , result.reason );
mail.queue( );
} catch ( Exception e ) {
throw new RuntimeException( e );
}
}
@Override
public void liftBan( Administrator admin , int id )
{
BanMailData result = this.bansDao.liftBan( admin.getId( ) , id );
if ( result == null ) {
return;
}
try {
MailData mail = this.mailer.createMail( result.language , "banLiftedMail" , result.address );
mail.queue( );
} catch ( Exception e ) {
throw new RuntimeException( e );
}
}
@Override
public AdminOverviewResponse getOverview( Administrator admin )
{
AdminOverview overview = this.adminDao.getOverview( admin.getId( ) );
if ( !admin.hasPrivilege( Privileges.NAME ) ) {
overview.setPendingNames( null );
}
if ( !admin.hasPrivilege( Privileges.BANH ) ) {
overview.setPendingBans( null );
}
if ( !admin.hasPrivilege( Privileges.BUGT ) ) {
overview.setPendingBugs( null );
overview.setOpenBugs( null );
overview.setUpdatedBugs( null );
}
return new AdminOverviewResponse( admin , overview );
}
}

View file

@ -0,0 +1,284 @@
package com.deepclone.lw.beans.admin;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.admin.bans.ArchivedBanRequest;
import com.deepclone.lw.cmd.admin.bans.BanRequest;
import com.deepclone.lw.cmd.admin.bans.BanType;
import com.deepclone.lw.cmd.admin.bans.SummaryEntry;
import com.deepclone.lw.cmd.admin.bans.ValidatedBanRequest;
import com.deepclone.lw.interfaces.admin.BanMailData;
import com.deepclone.lw.interfaces.admin.BansDAO;
import com.deepclone.lw.utils.EmailAddress;
import com.deepclone.lw.utils.StoredProc;
public class BansDAOBean
implements BansDAO
{
private static final String sGetPending = "SELECT * FROM admin.pending_bans ORDER BY requested DESC";
private static final String sGetArchived = "SELECT * FROM admin.cancelled_bans ORDER BY updated DESC";
private static final String sGetValidated = "SELECT * FROM admin.active_bans ORDER BY updated DESC";
private static final String sGetBan = "SELECT * FROM admin.active_bans WHERE account_mail = ?";
private static abstract class BanRequestMapper< T extends BanRequest >
implements RowMapper< T >
{
protected void getCommonData( BanRequest br , ResultSet rs )
throws SQLException
{
br.setId( rs.getInt( "id" ) );
br.setRequestedById( rs.getInt( "requested_by_id" ) );
br.setRequestedByName( rs.getString( "requested_by_name" ) );
br.setAccountId( rs.getInt( "account_id" ) );
br.setAccountMail( rs.getString( "account_mail" ) );
br.setTimestamp( rs.getTimestamp( "requested" ) );
br.setReason( rs.getString( "reason" ) );
}
}
private SimpleJdbcTemplate dTemplate;
private final BanRequestMapper< BanRequest > mPending;
private final BanRequestMapper< BanRequest > mArchived;
private final BanRequestMapper< BanRequest > mValidated;
private final RowMapper< Boolean > mBoolean;
private StoredProc fRequestBanAddress;
private StoredProc fRequestBanEmpire;
private StoredProc fRejectBan;
private StoredProc fValidateBan;
private StoredProc fLiftBan;
public BansDAOBean( )
{
this.mPending = new BanRequestMapper< BanRequest >( ) {
@Override
public BanRequest mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BanRequest br = new BanRequest( );
this.getCommonData( br , rs );
return br;
}
};
this.mArchived = new BanRequestMapper< BanRequest >( ) {
@Override
public BanRequest mapRow( ResultSet rs , int rowNum )
throws SQLException
{
ArchivedBanRequest br = new ArchivedBanRequest( );
this.getCommonData( br , rs );
br.setUpdate( rs.getTimestamp( "updated" ) );
br.setExpired( rs.getBoolean( "expired" ) );
if ( !br.isExpired( ) ) {
br.setRejectedById( rs.getInt( "rejected_by_id" ) );
br.setRejectedByName( rs.getString( "rejected_by_name" ) );
br.setRejectionReason( rs.getString( "rejection_reason" ) );
}
return br;
}
};
this.mValidated = new BanRequestMapper< BanRequest >( ) {
@Override
public BanRequest mapRow( ResultSet rs , int rowNum )
throws SQLException
{
ValidatedBanRequest br = new ValidatedBanRequest( );
this.getCommonData( br , rs );
br.setUpdate( rs.getTimestamp( "updated" ) );
br.setRedeemable( rs.getBoolean( "redeemable" ) );
br.setValidatedById( rs.getInt( "validated_by_id" ) );
br.setValidatedByName( rs.getString( "validated_by_name" ) );
return br;
}
};
this.mBoolean = new RowMapper< Boolean >( ) {
@Override
public Boolean mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return rs.getBoolean( 1 );
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fRequestBanAddress = new StoredProc( dataSource , "admin" , "request_ban_on_address" );
this.fRequestBanAddress.addParameter( "admin_id" , Types.INTEGER );
this.fRequestBanAddress.addParameter( "user_address" , Types.VARCHAR );
this.fRequestBanAddress.addParameter( "reason" , Types.VARCHAR );
this.fRequestBanAddress.addOutput( "err_code" , Types.INTEGER );
this.fRequestBanEmpire = new StoredProc( dataSource , "admin" , "request_ban_on_empire" );
this.fRequestBanEmpire.addParameter( "admin_id" , Types.INTEGER );
this.fRequestBanEmpire.addParameter( "user_address" , Types.VARCHAR );
this.fRequestBanEmpire.addParameter( "reason" , Types.VARCHAR );
this.fRequestBanEmpire.addOutput( "err_code" , Types.INTEGER );
this.fRejectBan = new StoredProc( dataSource , "admin" , "reject_ban_request" );
this.fRejectBan.addParameter( "admin_id" , Types.INTEGER );
this.fRejectBan.addParameter( "request_id" , Types.INTEGER );
this.fRejectBan.addParameter( "reason" , Types.VARCHAR );
this.fValidateBan = new StoredProc( dataSource , "admin" , "confirm_ban_request" );
this.fValidateBan.addParameter( "admin_id" , Types.INTEGER );
this.fValidateBan.addParameter( "request_id" , Types.INTEGER );
this.fValidateBan.addOutput( "success" , Types.BOOLEAN );
this.fValidateBan.addOutput( "addr" , Types.VARCHAR );
this.fValidateBan.addOutput( "lang" , Types.VARCHAR );
this.fValidateBan.addOutput( "r_txt" , Types.VARCHAR );
this.fLiftBan = new StoredProc( dataSource , "admin" , "lift_ban" );
this.fLiftBan.addParameter( "admin_id" , Types.INTEGER );
this.fLiftBan.addParameter( "request_id" , Types.INTEGER );
this.fLiftBan.addOutput( "success" , Types.BOOLEAN );
this.fLiftBan.addOutput( "addr" , Types.VARCHAR );
this.fLiftBan.addOutput( "lang" , Types.VARCHAR );
}
@Override
public List< SummaryEntry > getSummary( )
{
List< SummaryEntry > result = new ArrayList< SummaryEntry >( 3 );
final String names[] = {
"pending" , "cancelled" , "active"
};
for ( int i = 0 ; i < 3 ; i++ ) {
long count = this.dTemplate.queryForLong( "SELECT count(*) FROM admin." + names[ i ] + "_bans" );
result.add( new SummaryEntry( BanType.values( )[ i ] , count ) );
}
return result;
}
@Override
public List< BanRequest > getPending( )
{
return this.dTemplate.query( sGetPending , this.mPending );
}
@Override
public List< BanRequest > getArchived( )
{
return this.dTemplate.query( sGetArchived , this.mArchived );
}
@Override
public List< BanRequest > getActive( )
{
return this.dTemplate.query( sGetValidated , this.mValidated );
}
private int requestBan( StoredProc fRequestBan , int administrator , String address , String reason )
{
return (Integer) fRequestBan.execute( administrator , address , reason ).get( "err_code" );
}
@Override
public int requestBan( int administrator , EmailAddress address , String reason )
{
return this.requestBan( this.fRequestBanAddress , administrator , address.getAddress( ) , reason );
}
@Override
public int requestBan( int administrator , String empire , String reason )
{
return this.requestBan( this.fRequestBanEmpire , administrator , empire , reason );
}
@Override
public void rejectBan( int administrator , int requestId , String reason )
{
this.fRejectBan.execute( administrator , requestId , reason );
}
@Override
public BanMailData validateBan( int administrator , int requestId )
{
Map< String , Object > result = this.fValidateBan.execute( administrator , requestId );
boolean success = (Boolean) result.get( "success" );
if ( !success ) {
return null;
}
return new BanMailData( (String) result.get( "addr" ) , (String) result.get( "lang" ) , (String) result
.get( "r_txt" ) );
}
@Override
public BanMailData liftBan( int administrator , int requestId )
{
Map< String , Object > result = this.fLiftBan.execute( administrator , requestId );
boolean success = (Boolean) result.get( "success" );
if ( !success ) {
return null;
}
return new BanMailData( (String) result.get( "addr" ) , (String) result.get( "lang" ) );
}
@Override
public void expireBanRequests( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT admin.expire_ban_requests( )" );
}
@Override
public void expireWarnings( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT admin.expire_warnings( )" );
}
@Override
public boolean finaliseBan( )
{
String sql = "SELECT admin.delete_banned_empires( )";
return this.dTemplate.queryForObject( sql , this.mBoolean );
}
@Override
public ValidatedBanRequest getActiveBan( EmailAddress address )
{
try {
return (ValidatedBanRequest) this.dTemplate.queryForObject( sGetBan , this.mValidated , address
.getAddress( ) );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
}

View file

@ -0,0 +1,62 @@
package com.deepclone.lw.beans.admin;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.admin.BansDAO;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class BansProcessorBean
implements InitializingBean , DisposableBean
{
private Ticker ticker;
private BansProcessorTask task;
private TransactionTemplate tTemplate;
private BansDAO bansDao;
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setBansDao( BansDAO bansDao )
{
this.bansDao = bansDao;
}
@Override
public void afterPropertiesSet( )
throws Exception
{
this.task = new BansProcessorTask( this.tTemplate , this.bansDao );
this.ticker.registerTask( Frequency.LOW , "Bans processor" , this.task );
}
@Override
public void destroy( )
throws Exception
{
this.task = null;
}
}

View file

@ -0,0 +1,62 @@
package com.deepclone.lw.beans.admin;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.admin.BansDAO;
class BansProcessorTask
implements Runnable
{
private final TransactionTemplate tTemplate;
private final BansDAO bansDao;
public BansProcessorTask( TransactionTemplate tTemplate , BansDAO bansDao )
{
this.tTemplate = tTemplate;
this.bansDao = bansDao;
}
@Override
public void run( )
{
this.expire( );
while ( this.finaliseBans( ) ) {
// EMPTY
}
}
private boolean finaliseBans( )
{
return this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
@Override
public Boolean doInTransaction( TransactionStatus status )
{
return bansDao.finaliseBan( );
}
} );
}
private void expire( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
bansDao.expireBanRequests( );
bansDao.expireWarnings( );
}
} );
}
}

View file

@ -0,0 +1,87 @@
package com.deepclone.lw.beans.admin;
import java.net.InetAddress;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.deepclone.lw.interfaces.admin.IpBan;
/**
* The IP Ban bean specifies a private map container to hold IP Address ban entries. It also
* provides a public method to check whether a specified IP address is banned and a public method to
* increaes the counter of a given IP address.
*
* @author tseeker
*
*/
public class IpBanBean
implements IpBan
{
/**
* Static class with the date the ban was last increased and the counter of times increased.
*/
private static class BanEntry
{
public Date lastIncrease = new Date( );
public int counter = 1;
}
/** Private HashMap containing current IP addresses and their associated BanEntry's */
private final Map< InetAddress , BanEntry > entries = new HashMap< InetAddress , BanEntry >( );
/**
* Checks if an IP address is banned. An address is banned if an entry already exists for it, if
* the ban's duration has been reset in the last hour and the IP address's counter has been
* increased 3 or more times. If the ban is more than an hour old it is removed.
*/
@Override
public boolean isBanned( InetAddress address )
{
synchronized ( this.entries ) {
BanEntry entry = this.entries.get( address );
if ( entry == null ) {
return false;
}
if ( entry.lastIncrease.before( new Date( new Date( ).getTime( ) - 60 * 60 * 1000 ) ) ) {
this.entries.remove( address );
return false;
}
if ( entry.counter < 3 ) {
return false;
}
entry.lastIncrease = new Date( );
return true;
}
}
/**
* If the given IP address does not already have an entry associated with it, one is created for
* it. If it does, the entries counter is increased by 1.
*/
@Override
public void increaseBanCounter( InetAddress address )
{
synchronized ( this.entries ) {
BanEntry entry = this.entries.get( address );
if ( entry == null ) {
entry = new BanEntry( );
this.entries.put( address , entry );
return;
}
entry.counter++;
entry.lastIncrease = new Date( );
}
}
}

View file

@ -0,0 +1,28 @@
package com.deepclone.lw.beans.prefs;
class BoolPreferenceType
extends PreferenceTypeImpl< Boolean >
{
public BoolPreferenceType( )
{
super( Boolean.class );
}
@Override
public String convert( Object value )
{
Boolean v = (Boolean) value;
return ( v != null && v ) ? "1" : "0";
}
@Override
public Boolean valueOf( String dbValue , Class< Boolean > type )
{
return "1".equals( dbValue );
}
}

View file

@ -0,0 +1,79 @@
package com.deepclone.lw.beans.prefs;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import com.deepclone.lw.cmd.player.gdata.MailPreference;
import com.deepclone.lw.cmd.player.gdata.MapSize;
import com.deepclone.lw.interfaces.prefs.PreferenceDefinitions;
public class DefaultPreferencesBean
implements InitializingBean
{
private PreferenceDefinitions pDefs;
private PreferenceTypesRegistryBean registry;
@Autowired( required = true )
public void setTypesRegistry( PreferenceTypesRegistryBean registry )
{
this.registry = registry;
}
@Autowired( required = true )
public void setPreferenceDefinitions( PreferenceDefinitions preferenceDefinitions )
{
this.pDefs = preferenceDefinitions;
}
@Override
public void afterPropertiesSet( )
throws Exception
{
this.createTypes( );
this.pDefs.registerGroup( "display" , "pgDisplay" );
this.pDefs.registerPreference( "useRLTime" , "display" , "pUseRLTime" , "pUseRLTimeDescription" ,
(Boolean) false );
this.pDefs.registerGroup( "map" , "pgMap" );
this.pDefs.registerPreference( "mapX" , "map" , "pMapX" , "pMapXDescription" , (Integer) 0 );
this.pDefs.registerPreference( "mapY" , "map" , "pMapY" , "pMapYDescription" , (Integer) 0 );
this.pDefs.registerPreference( "mapSize" , "map" , "pMapSize" , "pMapSizeDescription" , MapSize.MEDIUM );
this.pDefs.registerGroup( "mail" , "pgMail" );
this.pDefs.registerPreference( "mailOnPM" , "mail" , "pMailOnPM" , "pMailOnPMDescription" ,
MailPreference.INSTANT );
this.pDefs.registerPreference( "mailOnAlliance" , "mail" , "pMailOnAlliance" , "pMailOnAllianceDescription" ,
MailPreference.DAILY_RECAP );
this.pDefs.registerPreference( "mailOnIM" , "mail" , "pMailOnIM" , "pMailOnIMDescription" ,
MailPreference.DAILY_RECAP );
this.pDefs.registerPreference( "mailOnAdmin" , "mail" , "pMailOnAdmin" , "pMailOnAdminDescription" ,
MailPreference.INSTANT );
}
private void createTypes( )
{
EnumPreferenceType< MapSize > mapSizeType;
mapSizeType = new EnumPreferenceType< MapSize >( MapSize.class );
mapSizeType.setTranslation( MapSize.SMALL , "mapSizeSmall" );
mapSizeType.setTranslation( MapSize.MEDIUM , "mapSizeMedium" );
mapSizeType.setTranslation( MapSize.LARGE , "mapSizeLarge" );
this.registry.register( mapSizeType );
EnumPreferenceType< MailPreference > mailPrefType;
mailPrefType = new EnumPreferenceType< MailPreference >( MailPreference.class );
mailPrefType.setTranslation( MailPreference.NO_MAIL , "mailPrefNo" );
mailPrefType.setTranslation( MailPreference.DAILY_RECAP , "mailPrefRecap" );
mailPrefType.setTranslation( MailPreference.INSTANT , "mailPrefInstant" );
this.registry.register( mailPrefType );
}
}

View file

@ -0,0 +1,63 @@
package com.deepclone.lw.beans.prefs;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
public class EnumPreferenceType< T >
extends PreferenceTypeImpl< T >
{
private SortedMap< T , String > choices = new TreeMap< T , String >( );
public EnumPreferenceType( Class< T > type )
{
super( type );
if ( !type.isEnum( ) ) {
throw new IllegalArgumentException( "Enumerated type expected" );
}
}
@Override
public Map< String , String > getChoices( )
{
Map< String , String > r = new LinkedHashMap< String , String >( );
for ( Map.Entry< T , String > entry : this.choices.entrySet( ) ) {
r.put( this.convert( entry.getKey( ) ) , entry.getValue( ) );
}
return r;
}
public void setTranslation( T value , String textId )
{
this.choices.put( value , textId );
}
@Override
@SuppressWarnings( "unchecked" )
public String convert( Object value )
{
return ( (T) value ).toString( );
}
@SuppressWarnings( "unchecked" )
@Override
public T valueOf( String dbValue , Class< T > type )
{
try {
return (T) type.getMethod( "valueOf" , String.class ).invoke( null , dbValue );
} catch ( Exception e ) {
throw new RuntimeException( e );
}
}
}

View file

@ -0,0 +1,31 @@
package com.deepclone.lw.beans.prefs;
class IntPreferenceType
extends PreferenceTypeImpl< Integer >
{
public IntPreferenceType( )
{
super( Integer.class );
}
@Override
public String convert( Object value )
{
return ( value == null ) ? "0" : ( (Integer) value ).toString( );
}
@Override
public Integer valueOf( String dbValue , Class< Integer > type )
{
try {
return Integer.parseInt( dbValue );
} catch ( NumberFormatException e ) {
return null;
}
}
}

View file

@ -0,0 +1,278 @@
package com.deepclone.lw.beans.prefs;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.cmd.admin.adata.Administrator;
import com.deepclone.lw.cmd.admin.logs.LogLevel;
import com.deepclone.lw.cmd.player.gdata.account.PrefCategory;
import com.deepclone.lw.cmd.player.gdata.account.PrefChoice;
import com.deepclone.lw.cmd.player.gdata.account.PrefType;
import com.deepclone.lw.cmd.player.gdata.account.PrefValue;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.prefs.PreferenceDefinitionException;
import com.deepclone.lw.interfaces.prefs.PreferenceDefinitions;
import com.deepclone.lw.interfaces.prefs.PreferenceType;
import com.deepclone.lw.interfaces.prefs.PreferenceTypesRegistry;
import com.deepclone.lw.utils.StoredProc;
public class PreferenceDefinitionsBean
implements PreferenceDefinitions
{
private static class PrefDefRecord
{
final String groupName;
final String groupDisplay;
final String name;
final String dName;
final String dDescription;
final String type;
final String value;
public PrefDefRecord( ResultSet rs )
throws SQLException
{
this.groupName = rs.getString( "group_name" );
this.groupDisplay = rs.getString( "group_display" );
this.name = rs.getString( "name" );
this.dName = rs.getString( "d_name" );
this.dDescription = rs.getString( "d_desc" );
this.type = rs.getString( "java_type" );
this.value = rs.getString( "default_value" );
}
}
private TransactionTemplate tTemplate;
private PreferenceTypesRegistry registry;
private SystemLogger logger;
private Translator translator;
private SimpleJdbcTemplate dTemplate;
private StoredProc uocGroup;
private StoredProc uocDef;
private StoredProc fSetDefault;
private final RowMapper< PrefDefRecord > mPrefDef;
public PreferenceDefinitionsBean( )
{
this.mPrefDef = new RowMapper< PrefDefRecord >( ) {
@Override
public PrefDefRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return new PrefDefRecord( rs );
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.uocGroup = new StoredProc( dataSource , "defs" , "uoc_preference_group" );
this.uocGroup.addParameter( "name" , Types.VARCHAR );
this.uocGroup.addParameter( "display" , Types.VARCHAR );
this.uocGroup.addOutput( "success" , Types.BOOLEAN );
this.uocDef = new StoredProc( dataSource , "defs" , "uoc_preference" );
this.uocDef.addParameter( "g_name" , Types.VARCHAR );
this.uocDef.addParameter( "p_name" , Types.VARCHAR );
this.uocDef.addParameter( "d_name" , Types.VARCHAR );
this.uocDef.addParameter( "d_desc" , Types.VARCHAR );
this.uocDef.addParameter( "j_type" , Types.VARCHAR );
this.uocDef.addParameter( "d_val" , Types.VARCHAR );
this.uocDef.addOutput( "err_code" , Types.INTEGER );
this.fSetDefault = new StoredProc( dataSource , "defs" , "set_preference_default" );
this.fSetDefault.addParameter( "admin_id" , Types.INTEGER );
this.fSetDefault.addParameter( "pref_name" , Types.VARCHAR );
this.fSetDefault.addParameter( "default_value" , Types.VARCHAR );
}
@Autowired( required = true )
public void setTypesRegistry( PreferenceTypesRegistry registry )
{
this.registry = registry;
}
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager transactionManager )
{
this.tTemplate = new TransactionTemplate( transactionManager );
}
@Autowired( required = true )
public void setLogger( Logger logger )
{
this.logger = logger.getSystemLogger( "PreferenceDefinitions" );
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public void registerGroup( final String name , final String displayName )
throws PreferenceDefinitionException
{
boolean success = this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
@Override
public Boolean doInTransaction( TransactionStatus status )
{
return (Boolean) uocGroup.execute( name , displayName ).get( "success" );
}
} );
if ( !success ) {
throw new PreferenceDefinitionException( PreferenceDefinitionException.Error.MISSING_STRING );
}
this.logger.log( LogLevel.DEBUG , "registered preference group '" + name + "'" );
}
@Override
public void registerPreference( final String name , final String group , final String displayName ,
final String displayDescription , final Object defaultValue )
throws PreferenceDefinitionException
{
final Class< ? > type = defaultValue.getClass( );
final PreferenceType< ? > pType = this.registry.getType( type );
int errCode = this.tTemplate.execute( new TransactionCallback< Integer >( ) {
@Override
public Integer doInTransaction( TransactionStatus status )
{
return (Integer) uocDef.execute( group , name , displayName , displayDescription ,
type.getSimpleName( ) , pType.convert( defaultValue ) ).get( "err_code" );
}
} );
switch ( errCode ) {
case 0:
break;
case 1:
throw new PreferenceDefinitionException( PreferenceDefinitionException.Error.MISSING_GROUP );
case 2:
throw new PreferenceDefinitionException( PreferenceDefinitionException.Error.MISSING_STRING );
case 3:
throw new PreferenceDefinitionException( PreferenceDefinitionException.Error.INVALID_TYPE );
default:
throw new RuntimeException( "unknown error code " + errCode );
}
this.logger.log( LogLevel.DEBUG , "registered preference '" + name + "' in group '" + group + "'" );
}
private String translate( String strName )
{
try {
return this.translator.translate( "en" , strName );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
}
@Override
@Transactional
public List< PrefCategory > getDefaults( )
{
List< PrefCategory > categories = new LinkedList< PrefCategory >( );
PrefCategory currentCategory = null;
String catName = "";
for ( PrefDefRecord def : this.dTemplate.query( "SELECT * FROM defs.preferences_view" , this.mPrefDef ) ) {
// Make sure we're modifying the right category
if ( currentCategory == null || !def.groupName.equals( catName ) ) {
currentCategory = new PrefCategory( );
catName = def.groupName;
currentCategory.setName( this.translate( def.groupDisplay ) );
categories.add( currentCategory );
}
// Add value
PrefValue value = new PrefValue( );
value.setId( def.name );
value.setName( this.translate( def.dName ) );
value.setDescription( this.translate( def.dDescription ) );
value.setValue( def.value );
PreferenceType< ? > dType = this.registry.getType( def.type );
if ( dType.getType( ) == String.class ) {
value.setType( PrefType.STRING );
} else if ( dType.getType( ) == Integer.class ) {
value.setType( PrefType.INTEGER );
} else if ( dType.getType( ) == Boolean.class ) {
value.setType( PrefType.BOOLEAN );
} else {
Map< String , String > choices = dType.getChoices( );
List< PrefChoice > cList = new LinkedList< PrefChoice >( );
for ( Map.Entry< String , String > entry : choices.entrySet( ) ) {
cList.add( new PrefChoice( entry.getKey( ) , this.translate( entry.getValue( ) ) ) );
}
value.setType( PrefType.CHOICE );
value.setChoices( cList );
}
currentCategory.addValue( value );
}
return categories;
}
@Override
@Transactional
public void setDefault( Administrator admin , String preference , String value )
{
String sql = "SELECT * FROM defs.preferences_view WHERE name = ?";
PrefDefRecord def;
try {
def = this.dTemplate.queryForObject( sql , this.mPrefDef , preference );
} catch ( EmptyResultDataAccessException e ) {
return;
}
PreferenceType< ? > pType = this.registry.getType( def.type );
Object inObject = pType.valueOf( value );
if ( inObject != null ) {
String dbValue = pType.convert( inObject );
this.fSetDefault.execute( admin.getId( ) , preference , dbValue );
}
}
}

View file

@ -0,0 +1,42 @@
package com.deepclone.lw.beans.prefs;
import java.util.Map;
import com.deepclone.lw.interfaces.prefs.PreferenceType;
abstract class PreferenceTypeImpl< T >
implements PreferenceType< T >
{
private final Class< T > type;
public PreferenceTypeImpl( Class< T > type )
{
this.type = type;
}
@Override
public Object valueOf( String inValue )
{
return this.valueOf( inValue , this.type );
}
@Override
public Map< String , String > getChoices( )
{
return null;
}
public Class< T > getType( )
{
return type;
}
}

View file

@ -0,0 +1,66 @@
package com.deepclone.lw.beans.prefs;
import java.util.HashMap;
import java.util.Map;
import com.deepclone.lw.interfaces.prefs.PreferenceType;
import com.deepclone.lw.interfaces.prefs.PreferenceTypesRegistry;
public class PreferenceTypesRegistryBean
implements PreferenceTypesRegistry
{
private final Map< String , PreferenceType< ? >> types = new HashMap< String , PreferenceType< ? > >( );
public PreferenceTypesRegistryBean( )
{
this.register( new StringPreferenceType( ) );
this.register( new IntPreferenceType( ) );
this.register( new BoolPreferenceType( ) );
}
void register( PreferenceType< ? > type )
{
String name = type.getType( ).getSimpleName( );
synchronized ( this.types ) {
if ( this.types.containsKey( name ) ) {
throw new IllegalArgumentException( "Type '" + name + "' already registered." );
}
this.types.put( name , type );
}
}
@Override
@SuppressWarnings( "unchecked" )
public < T > PreferenceType< T > getType( Class< T > jType )
{
PreferenceType< T > type;
synchronized ( this.types ) {
type = (PreferenceType< T >) this.types.get( jType.getSimpleName( ) );
}
if ( type == null ) {
throw new IllegalArgumentException( "Type '" + jType.getSimpleName( ) + "' is not registered." );
}
return type;
}
@Override
public PreferenceType< ? > getType( String typeName )
{
PreferenceType< ? > type;
synchronized ( this.types ) {
type = (PreferenceType< ? >) this.types.get( typeName );
}
if ( type == null ) {
throw new IllegalArgumentException( "Type '" + typeName + "' is not registered." );
}
return type;
}
}

View file

@ -0,0 +1,164 @@
package com.deepclone.lw.beans.prefs;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.interfaces.prefs.AccountPreferences;
import com.deepclone.lw.interfaces.prefs.Preference;
import com.deepclone.lw.interfaces.prefs.PreferenceGroup;
import com.deepclone.lw.interfaces.prefs.PreferenceType;
import com.deepclone.lw.interfaces.prefs.PreferenceTypesRegistry;
import com.deepclone.lw.interfaces.prefs.PreferencesDAO;
import com.deepclone.lw.sqld.accounts.Account;
import com.deepclone.lw.utils.StoredProc;
public class PreferencesDAOBean
implements PreferencesDAO
{
private SimpleJdbcTemplate dTemplate;
private PreferenceTypesRegistry registry;
private StoredProc fReset;
private StoredProc fSetPref;
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fReset = new StoredProc( dataSource , "users" , "reset_preferences" );
this.fReset.addParameter( "a_id" , Types.INTEGER );
this.fSetPref = new StoredProc( dataSource , "users" , "set_preference" );
this.fSetPref.addParameter( "a_id" , Types.INTEGER );
this.fSetPref.addParameter( "p_name" , Types.VARCHAR );
this.fSetPref.addParameter( "p_value" , Types.VARCHAR );
}
@Autowired( required = true )
public void setTypesRegistry( PreferenceTypesRegistry registry )
{
this.registry = registry;
}
@Override
public AccountPreferences getPreferences( int accountId )
{
String sql = "SELECT * FROM users.preferences_view WHERE account_id = ?";
RowMapper< Map< String , String > > mapper = new RowMapper< Map< String , String > >( ) {
@Override
public Map< String , String > mapRow( ResultSet rs , int rowNum )
throws SQLException
{
final String[] names = {
"group_name" , "group_i18n_name" , "pref_name" , "pref_i18n_name" , "pref_i18n_description" ,
"pref_type" , "value"
};
Map< String , String > data = new HashMap< String , String >( );
for ( String n : names ) {
data.put( n , rs.getString( n ) );
}
return data;
}
};
List< PreferenceGroup > groups = new LinkedList< PreferenceGroup >( );
Map< String , String > prefGroups = new HashMap< String , String >( );
String last = null;
PreferenceGroup lg = null;
for ( Map< String , String > data : this.dTemplate.query( sql , mapper , accountId ) ) {
String gName = data.get( "group_name" );
if ( last == null || !last.equals( gName ) ) {
lg = new PreferenceGroup( gName , data.get( "group_i18n_name" ) );
groups.add( lg );
last = gName;
}
String pName = data.get( "pref_name" );
prefGroups.put( pName , gName );
PreferenceType< ? > prefType = this.registry.getType( data.get( "pref_type" ) );
new Preference( pName , lg , data.get( "pref_i18n_name" ) , data.get( "pref_i18n_description" ) , prefType ,
data.get( "value" ) );
}
return new AccountPreferences( groups , prefGroups );
}
@Override
public AccountPreferences getPreferences( Account account )
{
return this.getPreferences( account.getId( ) );
}
@Override
public void setPreferences( Account account , Map< String , String > values )
{
String sql = "SELECT pref_name , pref_type FROM users.preferences_view WHERE account_id = ?";
RowMapper< Map< String , String > > mapper = new RowMapper< Map< String , String > >( ) {
@Override
public Map< String , String > mapRow( ResultSet rs , int rowNum )
throws SQLException
{
final String[] names = {
"pref_name" , "pref_type"
};
Map< String , String > data = new HashMap< String , String >( );
for ( String n : names ) {
data.put( n , rs.getString( n ) );
}
return data;
}
};
for ( Map< String , String > def : this.dTemplate.query( sql , mapper , account.getId( ) ) ) {
String pName = def.get( "pref_name" );
PreferenceType< ? > pType = this.registry.getType( def.get( "pref_type" ) );
String inValue = values.get( pName );
if ( inValue == null ) {
continue;
}
Object inObject = pType.valueOf( inValue );
if ( inObject == null ) {
continue;
}
String dbValue = pType.convert( inObject );
this.fSetPref.execute( account.getId( ) , pName , dbValue );
}
}
@Override
public void resetPreferences( Account account )
{
this.fReset.execute( account.getId( ) );
}
}

View file

@ -0,0 +1,27 @@
package com.deepclone.lw.beans.prefs;
class StringPreferenceType
extends PreferenceTypeImpl< String >
{
public StringPreferenceType( )
{
super( String.class );
}
@Override
public String convert( Object value )
{
return ( value == null ) ? "" : (String) value;
}
@Override
public String valueOf( String dbValue , Class< String > type )
{
return dbValue;
}
}

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="accounts/account-cleanup-bean.xml" />
<import resource="accounts/account-management-bean.xml" />
<import resource="accounts/admin-dao-bean.xml" />
<import resource="accounts/admin-recap-bean.xml" />
<import resource="accounts/administration-bean.xml" />
<import resource="accounts/bans-dao-bean.xml" />
<import resource="accounts/bans-processor-bean.xml" />
<import resource="accounts/default-preferences-bean.xml" />
<import resource="accounts/ip-ban-bean.xml" />
<import resource="accounts/preference-definitions-bean.xml" />
<import resource="accounts/preferences-dao-bean.xml" />
<import resource="accounts/quit-processor-bean.xml" />
<import resource="accounts/requests-expiration-bean.xml" />
<import resource="accounts/user-session-dao-bean.xml" />
<import resource="accounts/users-dao-bean.xml" />
<import resource="accounts/vacation-processor-bean.xml" />
</beans>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="accountCleanup" class="com.deepclone.lw.beans.acm.AccountCleanupBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="accountManagement" class="com.deepclone.lw.beans.acm.AccountManagementBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="adminDao" class="com.deepclone.lw.beans.admin.AdminDAOBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="adminRecap" class="com.deepclone.lw.beans.admin.AdminRecapBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="administration" class="com.deepclone.lw.beans.admin.AdministrationBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="bansDao" class="com.deepclone.lw.beans.admin.BansDAOBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="bansProcessor" class="com.deepclone.lw.beans.admin.BansProcessorBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="defaultPreferences" class="com.deepclone.lw.beans.prefs.DefaultPreferencesBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="ipBan" class="com.deepclone.lw.beans.admin.IpBanBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="preferenceDefinitions" class="com.deepclone.lw.beans.prefs.PreferenceDefinitionsBean" />
<bean id="preferenceTypesRegistry" class="com.deepclone.lw.beans.prefs.PreferenceTypesRegistryBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="preferencesDAO" class="com.deepclone.lw.beans.prefs.PreferencesDAOBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="quitProcessor" class="com.deepclone.lw.beans.acm.QuitProcessorBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="requestsExpiration" class="com.deepclone.lw.beans.acm.RequestsExpirationBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="userSessionDao" class="com.deepclone.lw.beans.acm.UserSessionDAOBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="usersDAO" class="com.deepclone.lw.beans.acm.UsersDAOBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="vacationProcessor" class="com.deepclone.lw.beans.acm.VacationProcessorBean" />
</beans>