googleauth dependency added
member totp service logic added & test code added
This commit is contained in:
parent
5a982538c6
commit
2f453bc38d
6
pom.xml
6
pom.xml
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user