Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Backend
Commits
89b231b4
Commit
89b231b4
authored
Feb 21, 2014
by
Nick Martynenko
Committed by
Matija Obreza
Feb 22, 2014
Browse files
OAuth refresh token cleanup
parent
06a21a10
Changes
8
Hide whitespace changes
Inline
Side-by-side
src/main/java/org/genesys2/server/persistence/domain/OAuthAccessTokenPersistence.java
View file @
89b231b4
...
...
@@ -16,14 +16,17 @@
package
org.genesys2.server.persistence.domain
;
import
java.util.Collection
;
import
org.genesys2.server.model.oauth.OAuthAccessToken
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.Modifying
;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.data.repository.query.Param
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.Collection
;
import
java.util.Date
;
import
java.util.List
;
@Transactional
public
interface
OAuthAccessTokenPersistence
extends
JpaRepository
<
OAuthAccessToken
,
String
>
{
...
...
@@ -33,7 +36,17 @@ public interface OAuthAccessTokenPersistence extends JpaRepository<OAuthAccessTo
OAuthAccessToken
findByAuthenticationId
(
String
authenticationId
);
@Query
(
"delete from OAuthAccessToken where tokenId in (:ids)"
)
@Modifying
void
deleteByTokenIds
(
@Param
(
"ids"
)
List
<
String
>
tokenIds
);
@Query
(
"delete from OAuthAccessToken where refreshToken = ?1"
)
@Modifying
void
deleteByRefreshToken
(
String
value
);
@Query
(
"select tokenId from OAuthAccessToken where createdDate < ?1"
)
List
<
String
>
getIdsOlderThen
(
Date
date
);
@Query
(
"select refreshToken from OAuthAccessToken where tokenId in (:ids)"
)
List
<
String
>
getRefreshTokensByIds
(
@Param
(
"ids"
)
List
<
String
>
tokenIds
);
}
src/main/java/org/genesys2/server/persistence/domain/OAuthRefreshTokenPersistence.java
View file @
89b231b4
...
...
@@ -18,9 +18,18 @@ package org.genesys2.server.persistence.domain;
import
org.genesys2.server.model.oauth.OAuthRefreshToken
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.Modifying
;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.data.repository.query.Param
;
import
org.springframework.transaction.annotation.Transactional
;
import
java.util.List
;
@Transactional
public
interface
OAuthRefreshTokenPersistence
extends
JpaRepository
<
OAuthRefreshToken
,
String
>
{
@Query
(
"delete from OAuthRefreshToken where tokenId in (:ids)"
)
@Modifying
void
deleteByTokenIds
(
@Param
(
"ids"
)
List
<
String
>
tokenIds
);
}
src/main/java/org/genesys2/server/service/TokensCleanupService.java
0 → 100644
View file @
89b231b4
package
org.genesys2.server.service
;
import
org.springframework.transaction.annotation.Propagation
;
import
org.springframework.transaction.annotation.Transactional
;
public
interface
TokensCleanupService
{
@Transactional
(
propagation
=
Propagation
.
REQUIRES_NEW
,
readOnly
=
false
)
void
cleanupAccessAndRefreshTokens
();
}
src/main/java/org/genesys2/server/service/impl/TokensCleanupServiceImpl.java
0 → 100644
View file @
89b231b4
package
org.genesys2.server.service.impl
;
import
org.genesys2.server.persistence.domain.OAuthAccessTokenPersistence
;
import
org.genesys2.server.persistence.domain.OAuthRefreshTokenPersistence
;
import
org.genesys2.server.service.TokensCleanupService
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
org.springframework.stereotype.Service
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.concurrent.TimeUnit
;
@Service
(
"tokensCleanupService"
)
public
class
TokensCleanupServiceImpl
implements
TokensCleanupService
{
private
Logger
_logger
=
LoggerFactory
.
getLogger
(
getClass
());
@Value
(
"${scheduler.tokens.cleanup.hours}"
)
private
int
cleanupHours
;
@Autowired
private
OAuthAccessTokenPersistence
accessTokenPersistence
;
@Autowired
private
OAuthRefreshTokenPersistence
refreshTokenPersistence
;
@Scheduled
(
cron
=
"${scheduler.tokens.cleanup.expression}"
)
@Override
public
void
cleanupAccessAndRefreshTokens
()
{
_logger
.
info
(
"Start cleanup of tokens"
);
//calculate date
Date
olderThen
=
new
Date
(
System
.
currentTimeMillis
()
-
TimeUnit
.
HOURS
.
toMillis
(
cleanupHours
));
//get "old" access token ids
List
<
String
>
accessTokensIds
=
accessTokenPersistence
.
getIdsOlderThen
(
olderThen
);
_logger
.
debug
(
"Access tokens IDs ready to cleanup {}"
,
accessTokensIds
);
if
(!
accessTokensIds
.
isEmpty
()){
//get corresponding refresh token ids
List
<
String
>
refreshTokens
=
accessTokenPersistence
.
getRefreshTokensByIds
(
accessTokensIds
);
_logger
.
debug
(
"Refresh tokens IDs ready to cleanup {}"
,
accessTokensIds
);
//remove access token ids
accessTokenPersistence
.
deleteByTokenIds
(
accessTokensIds
);
//should not be empty
if
(
refreshTokens
.
isEmpty
()
||
refreshTokens
.
size
()
!=
accessTokensIds
.
size
()){
_logger
.
warn
(
"There is difference between refresh and access tokens"
);
}
if
(!
refreshTokens
.
isEmpty
()){
//remove refresh token ids
refreshTokenPersistence
.
deleteByTokenIds
(
refreshTokens
);
}
}
_logger
.
info
(
"Cleanup of tokens proceeded successfully"
);
}
}
src/main/java/org/genesys2/server/service/impl/UserServiceImpl.java
View file @
89b231b4
...
...
@@ -48,6 +48,7 @@ import org.springframework.security.core.GrantedAuthority;
import
org.springframework.security.core.authority.SimpleGrantedAuthority
;
import
org.springframework.security.core.context.SecurityContextHolder
;
import
org.springframework.security.core.userdetails.UsernameNotFoundException
;
import
org.springframework.security.crypto.password.NoOpPasswordEncoder
;
import
org.springframework.security.crypto.password.PasswordEncoder
;
import
org.springframework.stereotype.Service
;
import
org.springframework.transaction.annotation.Transactional
;
...
...
@@ -60,8 +61,8 @@ public class UserServiceImpl implements UserService {
@Autowired
private
UserPersistence
userPersistence
;
@Autowired
private
PasswordEncoder
passwordEncoder
;
@Autowired
(
required
=
false
)
private
PasswordEncoder
passwordEncoder
=
NoOpPasswordEncoder
.
getInstance
()
;
private
long
accountLockoutTime
=
5
*
60
*
1000
;
...
...
src/test/java/org/genesys2/server/test/JpaDataConfig.java
0 → 100644
View file @
89b231b4
package
org.genesys2.server.test
;
import
org.junit.Ignore
;
import
org.springframework.beans.factory.FactoryBean
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.config.PropertiesFactoryBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.PropertySource
;
import
org.springframework.core.env.Environment
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.dao.support.PersistenceExceptionTranslator
;
import
org.springframework.data.jpa.repository.config.EnableJpaRepositories
;
import
org.springframework.jdbc.datasource.DriverManagerDataSource
;
import
org.springframework.orm.hibernate4.HibernateExceptionTranslator
;
import
org.springframework.orm.jpa.JpaTransactionManager
;
import
org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
;
import
org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
;
import
org.springframework.transaction.PlatformTransactionManager
;
import
javax.persistence.EntityManagerFactory
;
import
javax.sql.DataSource
;
import
java.util.Properties
;
@Ignore
@Configuration
@PropertySource
(
"classpath:/spring/spring.properties"
)
@EnableJpaRepositories
(
basePackages
=
"org.genesys2.server.persistence"
,
repositoryImplementationPostfix
=
"CustomImpl"
,
entityManagerFactoryRef
=
"entityManagerFactory"
,
transactionManagerRef
=
"transactionManager"
)
public
class
JpaDataConfig
{
@Autowired
private
Environment
env
;
@Bean
(
name
=
"hibernateProperties"
)
public
PropertiesFactoryBean
hibernateProperties
()
throws
Exception
{
PropertiesFactoryBean
bean
=
new
PropertiesFactoryBean
();
bean
.
setLocation
(
new
ClassPathResource
(
"/spring/hibernate.properties"
));
return
bean
;
}
@Bean
(
name
=
"dataSource"
)
public
DataSource
dataSource
()
throws
Exception
{
DriverManagerDataSource
dataSource
=
new
DriverManagerDataSource
();
dataSource
.
setDriverClassName
(
env
.
getProperty
(
"db.driverClassName"
));
dataSource
.
setUrl
(
env
.
getProperty
(
"db.url"
));
dataSource
.
setUsername
(
env
.
getProperty
(
"db.username"
));
dataSource
.
setPassword
(
env
.
getProperty
(
"db.password"
));
return
dataSource
;
}
@Bean
(
name
=
"entityManagerFactory"
)
public
FactoryBean
<
EntityManagerFactory
>
entityManagerFactory
(
Properties
hibernateProperties
)
throws
Exception
{
LocalContainerEntityManagerFactoryBean
bean
=
new
LocalContainerEntityManagerFactoryBean
();
bean
.
setDataSource
(
dataSource
());
bean
.
setPersistenceUnitName
(
"spring-jpa"
);
bean
.
setPackagesToScan
(
"org.genesys2.server.model"
);
HibernateJpaVendorAdapter
jpaVendorAdapter
=
new
HibernateJpaVendorAdapter
();
jpaVendorAdapter
.
setShowSql
(
env
.
getProperty
(
"db.show.sql"
,
Boolean
.
TYPE
,
true
));
jpaVendorAdapter
.
setGenerateDdl
(
env
.
getProperty
(
"db.generate.ddl"
,
Boolean
.
TYPE
,
true
));
bean
.
setJpaProperties
(
hibernateProperties
);
bean
.
setJpaVendorAdapter
(
jpaVendorAdapter
);
return
bean
;
}
@Bean
(
name
=
"transactionManager"
)
public
PlatformTransactionManager
jpaTransactionManager
(
EntityManagerFactory
entityManagerFactory
)
throws
Exception
{
JpaTransactionManager
transactionManager
=
new
JpaTransactionManager
();
transactionManager
.
setDataSource
(
dataSource
());
transactionManager
.
setEntityManagerFactory
(
entityManagerFactory
);
return
transactionManager
;
}
@Bean
public
PersistenceExceptionTranslator
hibernateExceptionTranslator
()
{
return
new
HibernateExceptionTranslator
();
}
}
src/test/java/org/genesys2/server/test/JpaTest.java
0 → 100644
View file @
89b231b4
package
org.genesys2.server.test
;
import
org.genesys2.server.service.TokensCleanupService
;
import
org.genesys2.server.service.impl.TokensCleanupServiceImpl
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Import
;
import
org.springframework.test.context.ContextConfiguration
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
static
org
.
junit
.
Assert
.
fail
;
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@ContextConfiguration
(
classes
=
JpaTest
.
Config
.
class
,
initializers
=
PropertyPlacholderInitializer
.
class
)
public
class
JpaTest
{
@Import
(
JpaDataConfig
.
class
)
public
static
class
Config
{
@Bean
public
TokensCleanupService
tokensCleanupService
(){
return
new
TokensCleanupServiceImpl
();
}
}
//use it without @Scheduled
@Autowired
private
TokensCleanupService
tokensCleanupService
;
@Test
public
void
testCleanup
(){
try
{
tokensCleanupService
.
cleanupAccessAndRefreshTokens
();
}
catch
(
Exception
e
)
{
fail
(
"This should not have any exceptions!"
);
}
}
}
src/test/java/org/genesys2/server/test/PropertyPlacholderInitializer.java
0 → 100644
View file @
89b231b4
package
org.genesys2.server.test
;
import
org.junit.Ignore
;
import
org.springframework.beans.factory.BeanCreationException
;
import
org.springframework.beans.factory.config.PlaceholderConfigurerSupport
;
import
org.springframework.context.ApplicationContextInitializer
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.context.support.PropertySourcesPlaceholderConfigurer
;
import
org.springframework.core.io.support.PathMatchingResourcePatternResolver
;
import
org.springframework.core.io.support.ResourcePatternResolver
;
import
java.io.IOException
;
/**
* Initializing class for using "context:property-placeholder" within @Configuration classes
*/
@Ignore
public
class
PropertyPlacholderInitializer
implements
ApplicationContextInitializer
<
ConfigurableApplicationContext
>
{
@Override
public
void
initialize
(
ConfigurableApplicationContext
applicationContext
)
{
ResourcePatternResolver
resourcePatternResolver
=
new
PathMatchingResourcePatternResolver
();
PlaceholderConfigurerSupport
postProcessor
=
new
PropertySourcesPlaceholderConfigurer
();
try
{
postProcessor
.
setLocations
(
//add all properties
resourcePatternResolver
.
getResources
(
"classpath:**/*.properties"
)
);
}
catch
(
IOException
e
)
{
throw
new
BeanCreationException
(
"Could not create bean "
+
postProcessor
.
toString
(),
e
);
}
applicationContext
.
addBeanFactoryPostProcessor
(
postProcessor
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment