ログインまで

This commit is contained in:
N-SYSDES\r-suzuki 2018-07-31 16:49:08 +09:00
parent 9a77db8b2a
commit 7249317ea4
18 changed files with 318 additions and 44 deletions

View file

@ -108,6 +108,8 @@
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- hash -->
</dependencies>
<build>

View file

@ -16,8 +16,11 @@
package org.springframework.samples.petclinic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
/**
* PetClinic Spring Boot Application.
@ -26,10 +29,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
*
*/
@SpringBootApplication
public class PetClinicApplication {
public class PetClinicApplication{
public static void main(String[] args) {
SpringApplication.run(PetClinicApplication.class, args);
}
}

View file

@ -28,6 +28,8 @@ import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
@ -58,6 +60,16 @@ public class Owner extends Person {
@Digits(fraction = 0, integer = 10)
private String telephone;
@Column(name = "email")
@NotEmpty
private String email;
@Column(name = "password")
@NotEmpty
@Size(min=8)
@Pattern(regexp = "^[a-zA-Z0-9]+$")
private String password;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets;
@ -85,6 +97,22 @@ public class Owner extends Person {
this.telephone = telephone;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
protected Set<Pet> getPetsInternal() {
if (this.pets == null) {
this.pets = new HashSet<>();

View file

@ -15,6 +15,10 @@
*/
package org.springframework.samples.petclinic.owner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.samples.petclinic.PetClinicApplication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
@ -25,7 +29,12 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Map;
@ -36,9 +45,14 @@ import java.util.Map;
* @author Michael Isvy
*/
@Controller
class OwnerController {
class OwnerController{
@Autowired
HttpSession session;
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
@Autowired
HttpServletRequest request;
private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";
private final OwnerRepository owners;
@ -46,6 +60,7 @@ class OwnerController {
this.owners = clinicService;
}
@InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
@ -60,17 +75,25 @@ class OwnerController {
@PostMapping("/owners/new")
public String processCreationForm(@Valid Owner owner, BindingResult result) {
if (result.hasErrors()) {
if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
} else {
this.owners.save(owner);
String s=toEncryptedHashValue("SHA-512",owner.getPassword());
owner.setPassword(s);
this.owners.save(owner);
return "redirect:/owners/" + owner.getId();
}
}
@GetMapping("/owners/find")
public String initFindForm(Map<String, Object> model) {
@GetMapping("/owners/find")
public String initFindForm(Map<String, Object> model,Model model2) {
model.put("owner", new Owner());
boolean s=(boolean)session.getAttribute("flag");
if (s) {
model2.addAttribute("flag",true);
}
return "owners/findOwners";
}
@ -108,7 +131,7 @@ class OwnerController {
@PostMapping("/owners/{ownerId}/edit")
public String processUpdateOwnerForm(@Valid Owner owner, BindingResult result, @PathVariable("ownerId") int ownerId) {
if (result.hasErrors()) {
if (result.hasErrors()) {
return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
} else {
owner.setId(ownerId);
@ -130,4 +153,59 @@ class OwnerController {
return mav;
}
@GetMapping("/login")
public String login(Owner owner,Map<String, Object> model) {
return "login";
}
@PostMapping("/loginh")
public String loginh(@Valid Owner owner, BindingResult result, Map<String, Object> model,Model model2) {
if (owner.getPassword()!=null) {
String s=toEncryptedHashValue("SHA-512",owner.getPassword());
owner.setPassword(s);
Owner results1 = this.owners.findByEmailAndPass(owner.getEmail(),owner.getPassword());
if (results1!=null) {
model2.addAttribute("flag",true);
model2.addAttribute("loginName",results1.getLastName()+" Welcome");
session.setAttribute("flag", true);
return "welcome";
}
}
Owner results2 = this.owners.findByOrEmail(owner.getEmail());
Collection<Owner> results3 = this.owners.findByOrPass(owner.getPassword());
if (results2==null && results3.isEmpty()) {
result.rejectValue("email", "notFound", "not found");
result.rejectValue("password", "notFound", "not found");
return "login";
}else if (results2==null){
result.rejectValue("email", "notFound", "not found");
return "login";
}else if (results3.isEmpty()){
result.rejectValue("password", "notFound", "not found");
return "login";
}
return "login";
}
private String toEncryptedHashValue(String algorithmName, String value) {
MessageDigest md = null;
StringBuilder sb = null;
try {
md = MessageDigest.getInstance(algorithmName);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
md.update(value.getBytes());
sb = new StringBuilder();
for (byte b : md.digest()) {
String hex = String.format("%02x", b);
sb.append(hex);
}
return sb.toString();
}
}

View file

@ -53,6 +53,18 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
@Transactional(readOnly = true)
Owner findById(@Param("id") Integer id);
@Query("SELECT owner FROM Owner owner WHERE owner.email =:email AND owner.password = :password")
@Transactional(readOnly = true)
Owner findByEmailAndPass(@Param("email") String email,@Param("password") String password);
@Query("SELECT owner FROM Owner owner WHERE owner.email =:email")
@Transactional(readOnly = true)
Owner findByOrEmail(@Param("email") String email);
@Query("SELECT owner FROM Owner owner WHERE owner.password =:password")
@Transactional(readOnly = true)
Collection<Owner> findByOrPass(@Param("password") String password);
/**
* Save an {@link Owner} to the data store, either inserting or updating it.
* @param owner the {@link Owner} to save

View file

@ -1,14 +1,30 @@
package org.springframework.samples.petclinic.system;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
class WelcomeController {
@Autowired
HttpSession session;
@Autowired
HttpServletRequest request;
@GetMapping("/")
public String welcome() {
public String welcome(Model model) {
session.setAttribute("flag", false);
model.addAttribute("flag",false);
return "welcome";
}
}

View file

@ -18,8 +18,10 @@ package org.springframework.samples.petclinic.visit;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import org.springframework.transaction.annotation.Transactional;
/**
* Repository class for <code>Visit</code> domain objects All method names are compliant with Spring Data naming
@ -42,4 +44,7 @@ public interface VisitRepository extends Repository<Visit, Integer> {
List<Visit> findByPetId(Integer petId);
}

View file

@ -22,16 +22,16 @@ INSERT INTO types VALUES (4, 'snake');
INSERT INTO types VALUES (5, 'bird');
INSERT INTO types VALUES (6, 'hamster');
INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023','a@a','1');
INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749','b@b','1');
INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763','c@c','1');
INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198','d@d','1');
INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765','e@e','1');
INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654','f@f','1');
INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387','g@g','1');
INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683','h@h','1');
INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435','i@i','1');
INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487','b@q.co.jp','4cb4e68337be40453bb04acf2fd2533c6c3d4d2a9ef3274bfc6fb2c56f06046fae449803654d362118633176f261f1c1d903f387ece406ccf7ec53262e0d04f0');
INSERT INTO pets VALUES (1, 'Leo', '2010-09-07', 1, 1);
INSERT INTO pets VALUES (2, 'Basil', '2012-08-06', 6, 2);

View file

@ -39,7 +39,9 @@ CREATE TABLE owners (
last_name VARCHAR_IGNORECASE(30),
address VARCHAR(255),
city VARCHAR(80),
telephone VARCHAR(20)
telephone VARCHAR(20),
email VARCHAR(255),
password VARCHAR(255)
);
CREATE INDEX owners_last_name ON owners (last_name);

View file

@ -6,3 +6,4 @@ nonNumeric=must be all numeric
duplicateFormSubmission=Duplicate form submission is not allowed
typeMismatch.date=invalid date
typeMismatch.birthDate=invalid date
login.error=has not been found

View file

@ -9,6 +9,8 @@
<div class="col-sm-10">
<div th:switch="${type}">
<input th:case="'text'" class="form-control" type="text" th:field="*{__${name}__}" />
<input th:case="'email'" class="form-control" type="email" th:field="*{__${name}__}" />
<input th:case="'password'" class="form-control" type="password" th:field="*{__${name}__}" / >
<input th:case="'date'" class="form-control" type="text" th:field="*{__${name}__}"
placeholder="YYYY-MM-DD" title="Enter a date in this format: YYYY-MM-DD"
pattern="(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))"/>

View file

@ -59,9 +59,9 @@
<span>Veterinarians</span>
</li>
<li th:replace="::menuItem ('/oups','error','trigger a RuntimeException to see how it is handled','warning-sign','Error')">
<li th:replace="::menuItem ('/login','login','trigger a RuntimeException to see how it is handled','warning-sign','login')">
<span class="glyphicon glyphicon-warning-sign" aria-hidden="true"></span>
<span>Error</span>
<span>Login</span>
</li>
</ul>

View file

@ -0,0 +1,20 @@
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'login')}">
<body>
<h2>Login</h2>
<form th:object="${owner}" th:action="@{/loginh}" class="form-horizontal" id="add-owner-form" method="post">
<div class="form-group has-feedback">
<input
th:replace="~{fragments/inputField :: input ('E-mail', 'email', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Password', 'password','password')}"/>
</div>
<div>
<button
class="btn btn-default" type="submit">Login</button>
</div>
</form>
</body>
</html>

View file

@ -16,12 +16,17 @@
th:replace="~{fragments/inputField :: input ('City', 'city', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Telephone', 'telephone', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('E-mail', 'email', 'text')}" />
<input
th:replace="~{fragments/inputField :: input ('Password', 'password', 'password')}" />
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button
th:with="text=${owner['new']} ? 'Add Owner' : 'Update Owner'"
class="btn btn-default" type="submit" th:text="${text}">Add
class="btn btn-default" type="submit" th:text="${text}">Find
Owner</button>
</div>
</div>

View file

@ -21,7 +21,7 @@
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Find
<button th:if="${flag}" type="submit" class="btn btn-default">Find
Owner</button>
</div>
</div>

View file

@ -3,8 +3,9 @@
<html xmlns:th="http://www.thymeleaf.org" th:replace="~{fragments/layout :: layout (~{::body},'home')}">
<body>
<h2 th:if="${flag}" th:text="${loginName}"></h2>
<h2 th:if="${!flag}">Welcome</h2>
<h2 th:text="#{welcome}">Welcome</h2>
<div class="row">
<div class="col-md-12">
<img class="img-responsive" src="../static/resources/images/pets.png" th:src="@{/resources/images/pets.png}"/>

View file

@ -9,6 +9,7 @@ import javax.validation.Validator;
import org.junit.Test;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.samples.petclinic.owner.Owner;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import static org.assertj.core.api.Assertions.assertThat;
@ -25,13 +26,13 @@ public class ValidatorTests {
return localValidatorFactoryBean;
}
@Test
@Test //fistnameが空白の時
public void shouldNotValidateWhenFirstNameEmpty() {
LocaleContextHolder.setLocale(Locale.ENGLISH);
Person person = new Person();
person.setFirstName("");
person.setLastName("smith");
person.setLastName("ああ");
Validator validator = createValidator();
Set<ConstraintViolation<Person>> constraintViolations = validator
@ -43,4 +44,91 @@ public class ValidatorTests {
assertThat(violation.getMessage()).isEqualTo("must not be empty");
}
@Test //lastnameが空白の時
public void shouldNotValidateWhenLastNameEmpty() {
LocaleContextHolder.setLocale(Locale.ENGLISH);
Person person = new Person();
person.setFirstName("aa");
person.setLastName("");
Validator validator = createValidator();
Set<ConstraintViolation<Person>> constraintViolations = validator
.validate(person);
assertThat(constraintViolations.size()).isEqualTo(1);
ConstraintViolation<Person> violation = constraintViolations.iterator().next();
assertThat(violation.getPropertyPath().toString()).isEqualTo("lastName");
assertThat(violation.getMessage()).isEqualTo("must not be empty");
}
@Test //addressが空白の時
public void shouldNotValidateWhenAddressEmpty() {
LocaleContextHolder.setLocale(Locale.ENGLISH);
Owner owner = new Owner();
owner.setFirstName("aa");
owner.setLastName("aa");
owner.setAddress("");
owner.setCity("sss");
owner.setTelephone("1988");
Validator validator = createValidator();
Set<ConstraintViolation<Owner>> constraintViolations = validator
.validate(owner);
assertThat(constraintViolations.size()).isEqualTo(1);
ConstraintViolation<Owner> violation = constraintViolations.iterator().next();
assertThat(violation.getPropertyPath().toString()).isEqualTo("address");
assertThat(violation.getMessage()).isEqualTo("must not be empty");
}
@Test //cityが空白の時
public void shouldNotValidateWhenCityEmpty() {
LocaleContextHolder.setLocale(Locale.ENGLISH);
Owner owner = new Owner();
owner.setFirstName("aa");
owner.setLastName("aa");
owner.setAddress("aaa");
owner.setCity("");
owner.setTelephone("1988");
Validator validator = createValidator();
Set<ConstraintViolation<Owner>> constraintViolations = validator
.validate(owner);
assertThat(constraintViolations.size()).isEqualTo(1);
ConstraintViolation<Owner> violation = constraintViolations.iterator().next();
assertThat(violation.getPropertyPath().toString()).isEqualTo("city");
assertThat(violation.getMessage()).isEqualTo("must not be empty");
}
@Test //telephoneが空白の時
public void shouldNotValidateWhenTelephoneEmpty() {
LocaleContextHolder.setLocale(Locale.ENGLISH);
Owner owner = new Owner();
owner.setFirstName("aa");
owner.setLastName("aa");
owner.setAddress("aaa");
owner.setCity("sss");
owner.setTelephone("");
Validator validator = createValidator();
Set<ConstraintViolation<Owner>> constraintViolations = validator
.validate(owner);
//assertThat(constraintViolations.size()).isEqualTo(1);
ConstraintViolation<Owner> violation = constraintViolations.iterator().next();
assertThat(violation.getPropertyPath().toString()).isEqualTo("telephone");
assertThat(violation.getMessage()).isEqualTo("must not be empty");
}
}

View file

@ -61,14 +61,14 @@ public class OwnerControllerTests {
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
}
@Test
@Test//日本語入力
public void testProcessCreationFormSuccess() throws Exception {
mockMvc.perform(post("/owners/new")
.param("firstName", "Joe")
.param("lastName", "Bloggs")
.param("firstName", "佐藤")
.param("lastName", "山田")
.param("address", "123 Caramel Street")
.param("city", "London")
.param("telephone", "01316761638")
.param("city", "アプリケーション")
.param("telephone", "0")
)
.andExpect(status().is3xxRedirection());
}
@ -76,9 +76,9 @@ public class OwnerControllerTests {
@Test
public void testProcessCreationFormHasErrors() throws Exception {
mockMvc.perform(post("/owners/new")
.param("firstName", "Joe")
.param("lastName", "Bloggs")
.param("city", "London")
.param("firstName", "山田")
.param("lastName", "鈴木")
.param("city", "佐藤")
)
.andExpect(status().isOk())
.andExpect(model().attributeHasErrors("owner"))
@ -103,7 +103,7 @@ public class OwnerControllerTests {
.andExpect(view().name("owners/ownersList"));
}
@Test
@Test///オーナー参照
public void testProcessFindFormByLastName() throws Exception {
given(this.owners.findByLastName(george.getLastName())).willReturn(Lists.newArrayList(george));
mockMvc.perform(get("/owners")
@ -124,15 +124,15 @@ public class OwnerControllerTests {
.andExpect(view().name("owners/findOwners"));
}
@Test
@Test//日本語での更新テスト
public void testInitUpdateOwnerForm() throws Exception {
mockMvc.perform(get("/owners/{ownerId}/edit", TEST_OWNER_ID))
.andExpect(status().isOk())
.andExpect(model().attributeExists("owner"))
.andExpect(model().attribute("owner", hasProperty("lastName", is("Franklin"))))
.andExpect(model().attribute("owner", hasProperty("firstName", is("George"))))
.andExpect(model().attribute("owner", hasProperty("address", is("110 W. Liberty St."))))
.andExpect(model().attribute("owner", hasProperty("city", is("Madison"))))
.andExpect(model().attribute("owner", hasProperty("lastName", is("ららら"))))
.andExpect(model().attribute("owner", hasProperty("firstName", is("ららららららラストネーム"))))
.andExpect(model().attribute("owner", hasProperty("address", is("いんと"))))
.andExpect(model().attribute("owner", hasProperty("city", is("大都会岡山"))))
.andExpect(model().attribute("owner", hasProperty("telephone", is("6085551023"))))
.andExpect(view().name("owners/createOrUpdateOwnerForm"));
}
@ -176,4 +176,13 @@ public class OwnerControllerTests {
.andExpect(view().name("owners/ownerDetails"));
}
@Test
public void testlogin() throws Exception {
mockMvc.perform(get("/loginh"))
.andExpect(status().isOk())
.andExpect(model().attribute("owner", hasProperty("email", is("b@q.co.jp"))))
.andExpect(model().attribute("owner", hasProperty("password", is("4cb4e68337be40453bb04acf2fd2533c6c3d4d2a9ef3274bfc6fb2c56f06046fae449803654d362118633176f261f1c1d903f387ece406ccf7ec53262e0d04f0"))))
.andExpect(view().name("welcome"));
}
}