Skip to content

Commit

Permalink
v2.10.0 release
Browse files Browse the repository at this point in the history
  • Loading branch information
jdubois committed May 7, 2015
1 parent 9f951ea commit 31a24e7
Show file tree
Hide file tree
Showing 37 changed files with 620 additions and 23 deletions.
1 change: 0 additions & 1 deletion .gitignore
Expand Up @@ -101,7 +101,6 @@ Desktop.ini
###################### ######################
/build/** /build/**
/bin/** /bin/**
/data/**
/spring_loaded/** /spring_loaded/**
/deploy/** /deploy/**


Expand Down
2 changes: 1 addition & 1 deletion Gruntfile.js
@@ -1,4 +1,4 @@
// Generated on 2015-04-29 using generator-jhipster 2.9.2 // Generated on 2015-05-07 using generator-jhipster 2.10.0
'use strict'; 'use strict';
var fs = require('fs'); var fs = require('fs');


Expand Down
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -41,9 +41,12 @@
"karma-requirejs": "0.2.2", "karma-requirejs": "0.2.2",
"karma-phantomjs-launcher": "0.1.4", "karma-phantomjs-launcher": "0.1.4",
"karma": "0.12.32", "karma": "0.12.32",
"generator-jhipster": "2.9.2", "generator-jhipster": "2.10.0",
"lodash": "3.3.1", "lodash": "3.3.1",
"xml2js": "0.4.5", "xml2js": "0.4.5",
"yo": ">=1.3.0",
"requirejs": "2.1",
"jasmine-core": "2.1.0",
"zeparser": "0.0.7", "zeparser": "0.0.7",
"wiredep": "2.2.2" "wiredep": "2.2.2"
}, },
Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Expand Up @@ -320,6 +320,12 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- Spring Cloud --> <!-- Spring Cloud -->
<dependency> <dependency>
Expand Down
27 changes: 21 additions & 6 deletions src/main/java/com/mycompany/myapp/Application.java
Expand Up @@ -18,6 +18,7 @@
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;


@ComponentScan @ComponentScan
@EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class}) @EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class})
Expand All @@ -33,13 +34,29 @@ public class Application {
* <p/> * <p/>
* Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile * Spring profiles can be configured with a program arguments --spring.profiles.active=your-active-profile
* <p/> * <p/>
* <p>
* You can find more information on how profiles work with JHipster on <a href="http://jhipster.github.io/profiles.html">http://jhipster.github.io/profiles.html</a>.
* </p>
*/ */
@PostConstruct @PostConstruct
public void initApplication() throws IOException { public void initApplication() throws IOException {
if (env.getActiveProfiles().length == 0) { if (env.getActiveProfiles().length == 0) {
log.warn("No Spring profile configured, running with default configuration"); log.warn("No Spring profile configured, running with default configuration");
} else { } else {
log.info("Running with Spring profile(s) : {}", Arrays.toString(env.getActiveProfiles())); log.info("Running with Spring profile(s) : {}", Arrays.toString(env.getActiveProfiles()));
Collection activeProfiles = Arrays.asList(env.getActiveProfiles());
if (activeProfiles.contains("dev") && activeProfiles.contains("prod")) {
log.error("You have misconfigured your application! " +
"It should not run with both the 'dev' and 'prod' profiles at the same time.");
}
if (activeProfiles.contains("prod") && activeProfiles.contains("fast")) {
log.error("You have misconfigured your application! " +
"It should not run with both the 'prod' and 'fast' profiles at the same time.");
}
if (activeProfiles.contains("dev") && activeProfiles.contains("cloud")) {
log.error("You have misconfigured your application! " +
"It should not run with both the 'dev' and 'cloud' profiles at the same time.");
}
} }
} }


Expand All @@ -49,11 +66,7 @@ public void initApplication() throws IOException {
public static void main(String[] args) throws UnknownHostException { public static void main(String[] args) throws UnknownHostException {
SpringApplication app = new SpringApplication(Application.class); SpringApplication app = new SpringApplication(Application.class);
app.setShowBanner(false); app.setShowBanner(false);

SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args); SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);

// Check if the selected profile has been set as argument.
// if not the development profile will be added
addDefaultProfile(app, source); addDefaultProfile(app, source);
addLiquibaseScanPackages(); addLiquibaseScanPackages();
Environment env = app.run(args).getEnvironment(); Environment env = app.run(args).getEnvironment();
Expand All @@ -67,10 +80,12 @@ public static void main(String[] args) throws UnknownHostException {
} }


/** /**
* Set a default profile if it has not been set * If no profile has been configured, set by default the "dev" profile.
*/ */
private static void addDefaultProfile(SpringApplication app, SimpleCommandLinePropertySource source) { private static void addDefaultProfile(SpringApplication app, SimpleCommandLinePropertySource source) {
if (!source.containsProperty("spring.profiles.active")) { if (!source.containsProperty("spring.profiles.active") &&
!System.getenv().containsKey("SPRING_PROFILES_ACTIVE")) {

app.setAdditionalProfiles(Constants.SPRING_PROFILE_DEVELOPMENT); app.setAdditionalProfiles(Constants.SPRING_PROFILE_DEVELOPMENT);
} }
} }
Expand Down
Expand Up @@ -52,7 +52,7 @@ public DataSource dataSource() {
log.debug("Configuring Datasource"); log.debug("Configuring Datasource");
if (propertyResolver.getProperty("url") == null && propertyResolver.getProperty("databaseName") == null) { if (propertyResolver.getProperty("url") == null && propertyResolver.getProperty("databaseName") == null) {
log.error("Your database connection pool configuration is incorrect! The application" + log.error("Your database connection pool configuration is incorrect! The application" +
"cannot start. Please check your Spring profile, current profiles are: {}", " cannot start. Please check your Spring profile, current profiles are: {}",
Arrays.toString(env.getActiveProfiles())); Arrays.toString(env.getActiveProfiles()));


throw new ApplicationContextException("Database connection pool is not configured correctly"); throw new ApplicationContextException("Database connection pool is not configured correctly");
Expand Down
Expand Up @@ -114,6 +114,8 @@ protected void configure(HttpSecurity http) throws Exception {
.antMatchers("/api/register").permitAll() .antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll() .antMatchers("/api/activate").permitAll()
.antMatchers("/api/authenticate").permitAll() .antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/account/reset_password/init").permitAll()
.antMatchers("/api/account/reset_password/finish").permitAll()
.antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/api/logs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/api/**").authenticated() .antMatchers("/api/**").authenticated()
.antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN) .antMatchers("/metrics/**").hasAuthority(AuthoritiesConstants.ADMIN)
Expand Down
Expand Up @@ -115,7 +115,7 @@ private void initCachingHttpHeadersFilter(ServletContext servletContext,
log.debug("Registering Caching HTTP Headers Filter"); log.debug("Registering Caching HTTP Headers Filter");
FilterRegistration.Dynamic cachingHttpHeadersFilter = FilterRegistration.Dynamic cachingHttpHeadersFilter =
servletContext.addFilter("cachingHttpHeadersFilter", servletContext.addFilter("cachingHttpHeadersFilter",
new CachingHttpHeadersFilter()); new CachingHttpHeadersFilter(env));


cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/assets/*"); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/assets/*");
cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/scripts/*"); cachingHttpHeadersFilter.addMappingForUrlPatterns(disps, true, "/scripts/*");
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/mycompany/myapp/domain/User.java
Expand Up @@ -6,13 +6,16 @@
import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.Email;


import javax.persistence.*; import javax.persistence.*;
import org.hibernate.annotations.Type;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern; import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;


import org.joda.time.DateTime;

/** /**
* A user. * A user.
*/ */
Expand Down Expand Up @@ -62,6 +65,14 @@ public class User extends AbstractAuditingEntity implements Serializable {
@JsonIgnore @JsonIgnore
private String activationKey; private String activationKey;


@Size(max = 20)
@Column(name = "reset_key", length = 20)
private String resetKey;

@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
@Column(name = "reset_date", nullable = true)
private DateTime resetDate = null;

@JsonIgnore @JsonIgnore
@ManyToMany @ManyToMany
@JoinTable( @JoinTable(
Expand Down Expand Up @@ -140,6 +151,22 @@ public void setActivationKey(String activationKey) {
this.activationKey = activationKey; this.activationKey = activationKey;
} }


public String getResetKey() {
return resetKey;
}

public void setResetKey(String resetKey) {
this.resetKey = resetKey;
}

public DateTime getResetDate() {
return resetDate;
}

public void setResetDate(DateTime resetDate) {
this.resetDate = resetDate;
}

public String getLangKey() { public String getLangKey() {
return langKey; return langKey;
} }
Expand Down
Expand Up @@ -4,7 +4,6 @@


import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.Query;


import java.util.List; import java.util.List;
Expand All @@ -19,6 +18,8 @@ public interface UserRepository extends JpaRepository<User, Long> {


List<User> findAllByActivatedIsFalseAndCreatedDateBefore(DateTime dateTime); List<User> findAllByActivatedIsFalseAndCreatedDateBefore(DateTime dateTime);


Optional<User> findOneByResetKey(String resetKey);

Optional<User> findOneByEmail(String email); Optional<User> findOneByEmail(String email);


Optional<User> findOneByLogin(String login); Optional<User> findOneByLogin(String login);
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/com/mycompany/myapp/service/MailService.java
Expand Up @@ -38,7 +38,7 @@ public class MailService {


@Inject @Inject
private MessageSource messageSource; private MessageSource messageSource;

@Inject @Inject
private SpringTemplateEngine templateEngine; private SpringTemplateEngine templateEngine;


Expand Down Expand Up @@ -83,4 +83,16 @@ public void sendActivationEmail(User user, String baseUrl) {
String subject = messageSource.getMessage("email.activation.title", null, locale); String subject = messageSource.getMessage("email.activation.title", null, locale);
sendEmail(user.getEmail(), subject, content, false, true); sendEmail(user.getEmail(), subject, content, false, true);
} }

@Async
public void sendPasswordResetMail(User user, String baseUrl) {
log.debug("Sending password reset e-mail to '{}'", user.getEmail());
Locale locale = Locale.forLanguageTag(user.getLangKey());
Context context = new Context(locale);
context.setVariable("user", user);
context.setVariable("baseUrl", baseUrl);
String content = templateEngine.process("passwordResetEmail", context);
String subject = messageSource.getMessage("email.reset.title", null, locale);
sendEmail(user.getEmail(), subject, content, false, true);
}
} }
29 changes: 29 additions & 0 deletions src/main/java/com/mycompany/myapp/service/UserService.java
Expand Up @@ -58,8 +58,37 @@ public Optional<User> activateRegistration(String key) {
return Optional.empty(); return Optional.empty();
} }


public Optional<User> completePasswordReset(String newPassword, String key) {
log.debug("Reset user password for reset key {}", key);

return userRepository.findOneByResetKey(key)
.filter(user -> {
DateTime oneDayAgo = DateTime.now().minusHours(24);
return user.getResetDate().isAfter(oneDayAgo.toInstant().getMillis());
})
.map(user -> {
user.setActivated(true);
user.setPassword(passwordEncoder.encode(newPassword));
user.setResetKey(null);
user.setResetDate(null);
userRepository.save(user);
return user;
});
}

public Optional<User> requestPasswordReset(String mail) {
return userRepository.findOneByEmail(mail)
.map(user -> {
user.setResetKey(RandomUtil.generateResetKey());
user.setResetDate(DateTime.now());
userRepository.save(user);
return user;
});
}

public User createUserInformation(String login, String password, String firstName, String lastName, String email, public User createUserInformation(String login, String password, String firstName, String lastName, String email,
String langKey) { String langKey) {

User newUser = new User(); User newUser = new User();
Authority authority = authorityRepository.findOne("ROLE_USER"); Authority authority = authorityRepository.findOne("ROLE_USER");
Set<Authority> authorities = new HashSet<>(); Set<Authority> authorities = new HashSet<>();
Expand Down
Expand Up @@ -29,4 +29,13 @@ public static String generatePassword() {
public static String generateActivationKey() { public static String generateActivationKey() {
return RandomStringUtils.randomNumeric(DEF_COUNT); return RandomStringUtils.randomNumeric(DEF_COUNT);
} }

/**
* Generates a reset key.
*
* @return the generated reset key
*/
public static String generateResetKey() {
return RandomStringUtils.randomNumeric(DEF_COUNT);
}
} }
@@ -1,5 +1,7 @@
package com.mycompany.myapp.web.filter; package com.mycompany.myapp.web.filter;


import org.springframework.core.env.Environment;

import javax.servlet.*; import javax.servlet.*;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
Expand All @@ -11,15 +13,20 @@
*/ */
public class CachingHttpHeadersFilter implements Filter { public class CachingHttpHeadersFilter implements Filter {


// Cache period is 1 month (in ms)
private final static long CACHE_PERIOD = TimeUnit.DAYS.toMillis(31L);

// We consider the last modified date is the start up time of the server // We consider the last modified date is the start up time of the server
private final static long LAST_MODIFIED = System.currentTimeMillis(); private final static long LAST_MODIFIED = System.currentTimeMillis();


private long CACHE_TIME_TO_LIVE = TimeUnit.DAYS.toMillis(31L);

private Environment env;

public CachingHttpHeadersFilter(Environment env) {
this.env = env;
}

@Override @Override
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
// Nothing to initialize CACHE_TIME_TO_LIVE = TimeUnit.DAYS.toMillis(env.getProperty("http.cache.timeToLiveInDays", Long.class, 31L));
} }


@Override @Override
Expand All @@ -31,11 +38,11 @@ public void destroy() {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) response; HttpServletResponse httpResponse = (HttpServletResponse) response;


httpResponse.setHeader("Cache-Control", "max-age=2678400000, public"); httpResponse.setHeader("Cache-Control", "max-age=" + CACHE_TIME_TO_LIVE + ", public");
httpResponse.setHeader("Pragma", "cache"); httpResponse.setHeader("Pragma", "cache");


// Setting Expires header, for proxy caching // Setting Expires header, for proxy caching
httpResponse.setDateHeader("Expires", CACHE_PERIOD + System.currentTimeMillis()); httpResponse.setDateHeader("Expires", CACHE_TIME_TO_LIVE + System.currentTimeMillis());


// Setting the Last-Modified header, for browser caching // Setting the Last-Modified header, for browser caching
httpResponse.setDateHeader("Last-Modified", LAST_MODIFIED); httpResponse.setDateHeader("Last-Modified", LAST_MODIFIED);
Expand Down
29 changes: 29 additions & 0 deletions src/main/java/com/mycompany/myapp/web/rest/AccountResource.java
Expand Up @@ -74,6 +74,7 @@ public ResponseEntity<?> registerAccount(@Valid @RequestBody UserDTO userDTO, Ht
}) })
); );
} }

/** /**
* GET /activate -> activate the registered user. * GET /activate -> activate the registered user.
*/ */
Expand Down Expand Up @@ -193,4 +194,32 @@ public void invalidateSession(@PathVariable String series) throws UnsupportedEnc
.findAny().ifPresent(t -> persistentTokenRepository.delete(decodedSeries)); .findAny().ifPresent(t -> persistentTokenRepository.delete(decodedSeries));
}); });
} }

@RequestMapping(value = "/account/reset_password/init",
method = RequestMethod.POST,
produces = MediaType.TEXT_PLAIN_VALUE)
@Timed
public ResponseEntity<?> requestPasswordReset(@RequestBody String mail, HttpServletRequest request) {

return userService.requestPasswordReset(mail)
.map(user -> {
String baseUrl = request.getScheme() +
"://" +
request.getServerName() +
":" +
request.getServerPort();
mailService.sendPasswordResetMail(user, baseUrl);
return new ResponseEntity<>("e-mail was sent", HttpStatus.OK);
}).orElse(new ResponseEntity<>("e-mail address not registered", HttpStatus.BAD_REQUEST));

}

@RequestMapping(value = "/account/reset_password/finish",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<String> finishPasswordReset(@RequestParam(value = "key") String key, @RequestParam(value = "newPassword") String newPassword) {
return userService.completePasswordReset(newPassword, key)
.map(user -> new ResponseEntity<String>(HttpStatus.OK)).orElse(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
}
} }
4 changes: 4 additions & 0 deletions src/main/resources/config/application-prod.yml
Expand Up @@ -47,6 +47,10 @@ metrics:
port: 2003 port: 2003
prefix: jhipster prefix: jhipster


http:
cache:
timeToLiveInDays: 31

cache: cache:
timeToLiveSeconds: 3600 timeToLiveSeconds: 3600
ehcache: ehcache:
Expand Down
Expand Up @@ -34,12 +34,16 @@
</column> </column>
<column name="lang_key" type="varchar(5)"/> <column name="lang_key" type="varchar(5)"/>
<column name="activation_key" type="varchar(20)"/> <column name="activation_key" type="varchar(20)"/>
<column name="reset_key" type="varchar(20)"/>
<column name="created_by" type="varchar(50)"> <column name="created_by" type="varchar(50)">
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>
<column name="created_date" type="timestamp" defaultValueDate="${now}"> <column name="created_date" type="timestamp" defaultValueDate="${now}">
<constraints nullable="false"/> <constraints nullable="false"/>
</column> </column>
<column name="reset_date" type="timestamp">
<constraints nullable="true"/>
</column>
<column name="last_modified_by" type="varchar(50)"/> <column name="last_modified_by" type="varchar(50)"/>
<column name="last_modified_date" type="timestamp"/> <column name="last_modified_date" type="timestamp"/>
</createTable> </createTable>
Expand Down

0 comments on commit 31a24e7

Please sign in to comment.