Skip to content

Commit

Permalink
Merge pull request #161 from JakduK/jakdu
Browse files Browse the repository at this point in the history
jsoup 연습 및 token TTL 적용
  • Loading branch information
pio authored Nov 27, 2016
2 parents 06c1655 + cd626d6 commit 2161e1d
Show file tree
Hide file tree
Showing 21 changed files with 103 additions and 168 deletions.
27 changes: 6 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The word ‘K LEAGUE JAKDU KING’ is formed by combining ‘K LEAGUE’, ‘JAK
The MIT License (MIT)

### Slack
If you join Slack, it's possible to talk.
If you join Slack, it's possible to talk. Please send email to me(phjang1983@daum.net), then send to an invitation email.
* https://jakduk.slack.com

### Finding contributors
Expand All @@ -31,26 +31,11 @@ This project is based on IntelliJ IDEA and Eclipse. You can import the project u
#### Dependency Management
* Gradle

#### Continuous integration Tool
* Jenkins

#### Database
* mongoDB

#### WAS
* Apache tmocat 8.x

#### Spring Framework 4.x
* Spring Core
* Spring Mvc
* Spring Security
* Spring Social
* Spring Data

#### Front end (CSS, Javascript)
* Bower
* Bootstrap
* JQuery
* AngularJS
* [Summernote](https://github.com/HackerWins/summernote), [angular-summernote](https://github.com/outsideris/angular-summernote)
* font-awesome
* Highcharts
* Slick

#### Spring Framework
* Spring Boot
1 change: 0 additions & 1 deletion api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ dependencies {

compile 'io.springfox:springfox-swagger2:2.6.1'
compile 'io.springfox:springfox-swagger-ui:2.6.1'
compile 'org.springframework.data:spring-data-rest-hal-browser:2.5.1.RELEASE'
compile 'io.jsonwebtoken:jjwt:0.7.0'
}

This file was deleted.

18 changes: 8 additions & 10 deletions api/src/main/java/com/jakduk/api/configuration/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Expand Down Expand Up @@ -65,23 +66,20 @@ protected void configure(HttpSecurity http) throws Exception {
.antMatchers(
"/api/login", // 로그인
"/auth/*", // SNS 인증
"/signup", // SNS 계정으로 회원 가입
"/user/social", // OAUTH2 콜백
"/user/write", // JakduK 회원 가입
"/user/*/write", // SNS 계정으로 회원 가입
"/password/*" // 비밀번호 찾기
"/signup" // SNS 계정으로 회원 가입
).anonymous()
.antMatchers(
HttpMethod.POST,
"/api/user", // 이메일 기반 회원 가입
"/api/user/social" // SNS 기반 회원 가입
).anonymous()
.antMatchers(
"/user/**",
// "/swagger-ui.html", // 스웨거
"/rest/**" // spring-data-rest
).authenticated()

// RESTful로 전환했기 때문에 바뀌어야 한다
.antMatchers(
"/board/*/write",
"/board/*/edit",
"/jakdu/write"

).hasAnyRole("USER_01", "USER_02", "USER_03")
.antMatchers(
"/admin/**",
Expand Down
24 changes: 15 additions & 9 deletions api/src/main/java/com/jakduk/api/configuration/SwaggerConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.ApiKeyVehicle;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

Expand Down Expand Up @@ -46,6 +49,7 @@ public Docket api() {
.host(environment.getProperty("swagger.host"))
.apiInfo(apiInfo())
.useDefaultResponseMessages(false)
.securitySchemes(Collections.singletonList(apiKey()))
.produces(producesList);
}

Expand All @@ -58,18 +62,20 @@ SecurityConfiguration security() {
"test-app",
"",
ApiKeyVehicle.HEADER,
"Authorization",
"",
"," /*scope separator*/);
}

private ApiInfo apiInfo() {
return new ApiInfo(
"JakduK REST API",
"Some custom description of API.",
"API TOS",
"Terms of service",
new Contact("pio.", "https://jakduk.com", "phjang1983@daum.net"),
"License of API",
"https://github.com/JakduK/JakduK/blob/master/LICENSE");
return new ApiInfoBuilder()
.title("JakduK REST API with Swagger")
.contact(new Contact("pio.", "https://jakduk.com", "phjang1983@daum.net"))
.license("The MIT License (MIT)")
.licenseUrl("https://github.com/JakduK/jakduk-api/blob/master/LICENSE")
.build();
}

private ApiKey apiKey() {
return new ApiKey("Authorization", "api_key", "header");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,15 @@
import com.jakduk.core.service.UserService;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.LocaleResolver;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.*;

@Slf4j
@Api(tags = "User", description = "회원 API")
Expand All @@ -51,15 +46,11 @@ public class PasswordRestController {
@Autowired
private EmailService emailService;

@Value("#{tokenTerminationTrigger.span}")
private long tokenSpan;

// jakduk 비밀번호 찾기 처리.
@RequestMapping(value = "/find", method = RequestMethod.POST)
public Map<String, Object> findPassword(@RequestParam String email,
@RequestParam String callbackUrl,
final Locale locale) {

Locale locale) {
String message = "";

UserProfile userProfile = userService.findOneByEmail(email);
Expand All @@ -71,6 +62,7 @@ public Map<String, Object> findPassword(@RequestParam String email,
case JAKDUK:
message = CoreUtils.getResourceBundleMessage("messages.user", "user.msg.reset.password.sendok");
try {

emailService.sendResetPassword(locale, callbackUrl, email);
} catch (MessagingException e) {
throw new ServiceException(ServiceError.SEND_EMAIL_FAILED);
Expand All @@ -95,21 +87,18 @@ public Map<String, Object> findPassword(@RequestParam String email,

// jakduk 비밀번호 재설정.
@RequestMapping(value = "/reset/{code}", method = RequestMethod.GET)
public Map<String, Object> resetPassword(@PathVariable String code,
HttpServletRequest request) {

Locale locale = localeResolver.resolveLocale(request);
public Map<String, Object> resetPassword(@PathVariable String code) {

if (Objects.isNull(code))
throw new IllegalArgumentException(CoreUtils.getExceptionMessage("exception.invalid.parameter"));

Map<String, Object> response = new HashMap<>();
Token token = commonService.getTokenByCode(code);
Optional<Token> oToken = commonService.getTokenByCode(code);

if (Objects.isNull(token) || !token.getCode().equals(code)) {
if (! oToken.isPresent() || ! StringUtils.equals(oToken.get().getCode(), code))
throw new IllegalArgumentException(CoreUtils.getResourceBundleMessage("messages.user", "user.msg.reset.password.invalid"));
}

Token token = oToken.get();
response.put("subject", token.getEmail());
response.put("code", token.getCode());

Expand All @@ -122,22 +111,20 @@ public Map<String, Object> updatePassword(
@RequestParam(value = "password") String password,
@RequestParam(value = "code") String code) {

long tokenSpanMillis = TimeUnit.MINUTES.toMillis(tokenSpan);
Token token = tokenRepository.findByCode(code);
Optional<Token> oToken = commonService.getTokenByCode(code);

Map<String, Object> response = new HashMap<>();
String message;

if (Objects.isNull(token) || token.getCreatedTime().getTime() + tokenSpanMillis <= System.currentTimeMillis()) {
message = CoreUtils.getResourceBundleMessage("messages.user", "user.msg.reset.password.invalid");
} else {
if (oToken.isPresent()) {
Token token = oToken.get();
userService.userPasswordUpdateByEmail(token.getEmail(), passwordEncoder.encode(password.trim()));
message = CoreUtils.getResourceBundleMessage("messages.user", "user.msg.success.change.password");
response.put("subject", token.getEmail());
}

if (Objects.nonNull(token)) {
tokenRepository.delete(token);
} else {
message = CoreUtils.getResourceBundleMessage("messages.user", "user.msg.reset.password.invalid");
}

response.put("message", message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public Boolean existUsernameOnAnonymous(@RequestParam() String username,

@ApiOperation(value = "이메일 중복 검사")
@RequestMapping(value = "/exist/email", method = RequestMethod.GET)
public EmptyJsonResponse existEmail(@NotEmpty @Email @RequestParam String email) {
public EmptyJsonResponse existEmail(@Valid @NotEmpty @Email @RequestParam String email) {

userService.existEmail(email.trim());

Expand All @@ -186,7 +186,7 @@ public EmptyJsonResponse existEmail(@NotEmpty @Email @RequestParam String email)

@ApiOperation(value = "별명 중복 검사")
@RequestMapping(value = "/exist/username", method = RequestMethod.GET)
public EmptyJsonResponse existUsername(@NotEmpty @RequestParam String username) {
public EmptyJsonResponse existUsername(@Valid @NotEmpty @RequestParam String username) {

userService.existUsername(username.trim());

Expand Down
3 changes: 2 additions & 1 deletion api/src/test/java/com/jakduk/api/AdminTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.jakduk.core.repository.board.free.BoardFreeRepositoryRepository;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.web.util.UrlUtils;

/**
* @author <a href="mailto:phjang1983@daum.net">Jang,Pyohwan</a>
Expand All @@ -27,7 +28,7 @@ public void getBoard() {
long boardCnt = 101;
int limit = 100;
int totalPage = (int)(boardCnt / limit);

System.out.println("boardCnt=" + boardCnt);
System.out.println("totalPage=" + totalPage);
}
Expand Down
2 changes: 0 additions & 2 deletions api/src/test/java/com/jakduk/api/common/CommonTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
import com.jakduk.core.service.CommonService;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Spy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;

Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@ subprojects {

compile group: 'org.jongo', name: 'jongo', version:'1.3.0'
compile group: 'commons-fileupload', name: 'commons-fileupload', version:'1.3.2'
compile group: 'commons-io', name: 'commons-io', version:'2.4'
compile group: 'commons-io', name: 'commons-io', version:'2.5'
compile group: 'rome', name: 'rome', version:'1.0'
compile group: 'io.searchbox', name: 'jest', version:'2.0.3'
compile group: 'net.gpedro.integrations.slack', name: 'slack-webhook', version:'1.1.1'
compile 'commons-beanutils:commons-beanutils:1.9.2'
compile group: 'net.gpedro.integrations.slack', name: 'slack-webhook', version:'1.2.1'
compile 'commons-beanutils:commons-beanutils:1.9.3'
compile 'net.coobird:thumbnailator:0.4.8'

compileOnly 'org.projectlombok:lombok:1.16.10'
Expand Down
2 changes: 2 additions & 0 deletions changelog/db_migration.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// token TTL 설정
db.token.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

Version 0.7.0 / 2016-07-27

Expand Down
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ description = 'core'

dependencies {
compile 'javax.persistence:persistence-api:1.0.2'
compile 'org.jsoup:jsoup:1.10.1'
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.jakduk.core.configuration;

import com.jakduk.core.trigger.TokenTerminationTrigger;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
Expand All @@ -20,14 +19,6 @@
@EnableAsync
public class CoreAsyncConfig implements AsyncConfigurer {

@Bean(initMethod = "init")
public TokenTerminationTrigger tokenTerminationTrigger() {
TokenTerminationTrigger tokenTerminationTrigger = new TokenTerminationTrigger();
tokenTerminationTrigger.setSpan(5);

return tokenTerminationTrigger;
}

@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
Expand Down
3 changes: 1 addition & 2 deletions core/src/main/java/com/jakduk/core/model/db/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@ public class Token {

@Id
private String email;

private String code;
private CommonConst.TOKEN_TYPE tokenType = CommonConst.TOKEN_TYPE.RESET_PASSWORD;

@Temporal(TemporalType.DATE)
private Date createdTime;
private Date expireAt;
}
Loading

0 comments on commit 2161e1d

Please sign in to comment.