googleauth dependency added

member totp service logic added & test code added
This commit is contained in:
geek 2018-03-09 18:09:07 +09:00
parent 5a982538c6
commit 2f453bc38d
10 changed files with 241 additions and 26 deletions

View File

@ -31,6 +31,7 @@
<jackson.mapper.version>1.9.13</jackson.mapper.version>
<apache.velocity.version>1.7</apache.velocity.version>
<docker.registry.name>docker.loafle.net/overflow</docker.registry.name>
<googleauth.version>1.1.2</googleauth.version>
</properties>
<dependencies>
@ -175,6 +176,11 @@
<version>1.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.warrenstrange</groupId>
<artifactId>googleauth</artifactId>
<version>${googleauth.version}</version>
</dependency>
</dependencies>
<build>

View File

@ -1,5 +1,6 @@
package com.loafle.overflow.module.member.dao;
import com.loafle.overflow.module.member.model.Member;
import com.loafle.overflow.module.member.model.MemberTotp;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
@ -13,4 +14,7 @@ import org.springframework.stereotype.Repository;
public interface MemberTotpDAO extends JpaRepository<MemberTotp, Long> {
@Query("select m from MemberTotp m WHERE m.secretCode = :secretCode")
MemberTotp findBySecretCode(@Param("secretCode") String secretCode);
MemberTotp findByMember(Member member);
}

View File

@ -22,7 +22,6 @@ public class Member {
private Date createDate;
private MetaMemberStatus status;
private int signinFailCount;
private MemberTotp totp;
private boolean totpType;
public Member() {
@ -122,17 +121,8 @@ public class Member {
this.signinFailCount = failCount;
}
@OneToOne
@JsonIgnore
@JoinColumn(name = "MEMBER_TOTP", nullable = true)
public MemberTotp getTotp() {
return totp;
}
public void setTotp(MemberTotp totp) {
this.totp = totp;
}
@Basic
@Column(name = "TOTP_TYPE", nullable = false, columnDefinition = "boolean default false")
public boolean isTotpType() {
return totpType;
}

View File

@ -1,5 +1,7 @@
package com.loafle.overflow.module.member.model;
import org.codehaus.jackson.annotate.JsonIgnore;
import javax.persistence.*;
import java.util.Date;
@ -7,12 +9,14 @@ import java.util.Date;
* Created by geek on 18. 3. 8.
*/
@Entity
@Table(name = "MEMBER", schema = "public")
@Table(name = "MEMBER_TOTP", schema = "public")
public class MemberTotp {
private long id;
private Member member;
private String secretCode;
private Date createDate;
private Date updateDate;
private String otpAuthURL;
public MemberTotp() {
}
@ -31,6 +35,16 @@ public class MemberTotp {
this.id = id;
}
@OneToOne
@JoinColumn(name = "MEMBER_ID", nullable = false)
public Member getMember() {
return member;
}
public void setMember(Member member) {
this.member = member;
}
@Basic
@Column(name = "SECRET_CODE", nullable = false, length = 20)
public String getSecretCode() {
@ -52,7 +66,7 @@ public class MemberTotp {
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "CREATE_DATE", nullable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", insertable = false, updatable = true)
@Column(name = "UPDATE_DATE", nullable = false, columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP", insertable = false, updatable = true)
public Date getUpdateDate() {
return updateDate;
}
@ -60,4 +74,13 @@ public class MemberTotp {
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
@Transient
public String getOtpAuthURL() {
return otpAuthURL;
}
public void setOtpAuthURL(String otpAuthURL) {
this.otpAuthURL = otpAuthURL;
}
}

View File

@ -163,19 +163,18 @@ public class MemberService {
public Member modify(Member member, String pw) {
String email = SessionMetadata.getEmail();
boolean checkPass = this.isPasswordStrong(pw);
if (!checkPass) {
throw new PasswordNotStrongException(
"Passwords must contain at least one uppercase letter, " +
"special character, lowercase letter, and number, " +
"and must be at least 6 characters long.");
}
Member preMember = this.memberDAO.findByEmail(member.getEmail());
if (null != pw && !pw.equals("")) {
boolean checkPass = this.isPasswordStrong(pw);
if (!checkPass) {
throw new PasswordNotStrongException(
"Passwords must contain at least one uppercase letter, " +
"special character, lowercase letter, and number, " +
"and must be at least 6 characters long.");
}
Boolean match = passwordEncoder.matches(member.getPw(), preMember.getPw());
if(!match) {
member.setPw(passwordEncoder.encode(pw));

View File

@ -1,5 +1,12 @@
package com.loafle.overflow.module.member.service;
import com.loafle.overflow.module.member.dao.MemberTotpDAO;
import com.loafle.overflow.module.member.model.Member;
import com.loafle.overflow.module.member.model.MemberTotp;
import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
@ -7,4 +14,64 @@ import org.springframework.stereotype.Service;
*/
@Service("MemberTotpService")
public class MemberTotpService {
@Autowired
private MemberTotpDAO totpDAO;
public MemberTotp regist(MemberTotp totp) throws Exception {
if ( null == totp.getSecretCode() || totp.getSecretCode().equals("")) {
throw new Exception("Not Null SecretCode");
}
if (null == totp.getMember() || 0 < totp.getMember().getId()) {
throw new Exception("Not Null Member ID");
}
return this.totpDAO.save(totp);
}
public MemberTotp modify(MemberTotp totp) throws Exception {
if ( null == totp.getSecretCode() || totp.getSecretCode().equals("")) {
throw new Exception("Not Null SecretCode");
}
if (null == totp.getMember() || 0 < totp.getMember().getId()) {
throw new Exception("Not Null Member ID");
}
return this.totpDAO.save(totp);
}
public void remove(long id) throws Exception {
this.totpDAO.delete(id);
}
public MemberTotp read(long id) throws Exception {
return this.totpDAO.findOne(id);
}
public boolean checkCode(MemberTotp totp, String code) throws Exception {
GoogleAuthenticator googleAuthenticator = new GoogleAuthenticator();
boolean isCheck = googleAuthenticator.authorize(totp.getSecretCode(), Integer.valueOf(code));
if (!isCheck) {
throw new Exception("Invalid Code");
}
return isCheck;
}
public MemberTotp createTotp(Member member) {
MemberTotp totp = new MemberTotp();
GoogleAuthenticator googleAuthenticator = new GoogleAuthenticator();
final GoogleAuthenticatorKey key = googleAuthenticator.createCredentials();
String secret = key.getKey();
// List<Integer> scratchCodes = key.getScratchCodes();
String otpAuthURL = GoogleAuthenticatorQRGenerator.getOtpAuthURL("overFlow", member.getEmail(), key);
totp.setMember(member);
totp.setSecretCode(secret);
totp.setOtpAuthURL(otpAuthURL);
return totp;
}
}

View File

@ -875,6 +875,12 @@ INSERT INTO public.domain_member (create_date,domain_id,member_id) VALUES (
INSERT INTO public.domain_member (create_date,domain_id,member_id) VALUES (
'2017-06-26 11:27:43.023',1,2);
-- Member TOTP Insert SQL
-- INSERT INTO public.member_totp (create_date, secret_code, update_date, member_id) VALUES(
-- '2018-03-09 16:39:57.304', 'EDPBZLDATGZP7NX2', '2018-03-09 16:39:57.304', 2);
-- Member TOTP Insert SQL
INSERT INTO public.api_key (api_key,create_date,domain_id) VALUES (
'52abd6fd57e511e7ac52080027658d13','2017-06-26 13:02:28.347',1);

View File

@ -0,0 +1,50 @@
package com.loafle.overflow.module.member.dao;
import com.loafle.overflow.module.member.model.Member;
import com.loafle.overflow.module.member.model.MemberTotp;
import com.loafle.overflow.spring.AppConfigTest;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
/**
* Created by geek on 18. 3. 9.
*/
@Ignore
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {AppConfigTest.class})
public class MemberTotpDAOTest {
@Autowired
private MemberTotpDAO dao;
@Test
public void insertTest() throws Exception {
MemberTotp totp = new MemberTotp();
totp.setSecretCode("AI6EWOYSZWEBAI2D");
totp.setMember(new Member(2));
this.dao.save(totp);
}
@Test
public void findBySecretCode() throws Exception {
}
@Test
public void findByMember() throws Exception {
MemberTotp totp = new MemberTotp();
totp.setSecretCode("EDPBZLDATGZP7NX2");
totp.setMember(new Member(2));
this.dao.save(totp);
MemberTotp totp1 = this.dao.findByMember(totp.getMember());
assertNotNull(totp1);
}
}

View File

@ -2,6 +2,7 @@ package com.loafle.overflow.module.member.service;
import com.loafle.overflow.module.domain.model.Domain;
import com.loafle.overflow.module.member.model.Member;
import com.loafle.overflow.module.member.model.MemberTotp;
import com.loafle.overflow.module.meta.model.MetaMemberStatus;
import com.loafle.overflow.spring.AppConfigTest;
import org.junit.Assert;
@ -29,6 +30,9 @@ public class MemberServiceTest {
@Autowired
MemberService memberService;
@Autowired
MemberTotpService totpService;
@Test
public void regist() throws Exception {
@ -47,8 +51,8 @@ public class MemberServiceTest {
@Test
public void signin() throws Exception {
Member m = this.memberService.signin("overflow@loafle.com", "!@#$qwer1234");
Assert.assertNotNull(m);
// Member m = this.memberService.signin("overflow@loafle.com", "!@#$qwer1234");
// Assert.assertNotNull(m);
}
@Test

View File

@ -0,0 +1,66 @@
package com.loafle.overflow.module.member.service;
import com.loafle.overflow.module.member.model.Member;
import com.loafle.overflow.module.member.model.MemberTotp;
import com.loafle.overflow.spring.AppConfigTest;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.*;
/**
* Created by geek on 18. 3. 9.
*/
@Ignore
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {AppConfigTest.class})
public class MemberTotpServiceTest {
@Autowired
private MemberTotpService totpService;
@Test
public void regist() throws Exception {
}
@Test
public void modify() throws Exception {
}
@Test
public void remove() throws Exception {
}
@Test
public void read() throws Exception {
}
@Test
public void checkCode() throws Exception {
MemberTotp totp = new MemberTotp();
totp.setSecretCode("PN44SRPS5QCGCJNS");
boolean isCheck = this.totpService.checkCode(totp, "125073");
System.out.println(isCheck);
}
@Test
public void createTotp() throws Exception {
Member m = new Member(2);
m.setEmail("geekdev@naver.com");
MemberTotp totp = this.totpService.createTotp(m);
System.out.println(totp.getSecretCode());
System.out.println(totp.getOtpAuthURL());
}
}