Added Login
This commit is contained in:
parent
af5248faed
commit
90ccb8a00c
33
build.gradle
33
build.gradle
@ -1,9 +1,20 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'org.flywaydb:flyway-database-postgresql:11.3.2'
|
||||||
|
classpath 'org.postgresql:postgresql:42.7.5'
|
||||||
|
}
|
||||||
|
}
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.springframework.boot' version '3.4.2'
|
id 'org.springframework.boot' version '3.4.2'
|
||||||
|
id 'org.flywaydb.flyway' version "11.3.2"
|
||||||
id 'io.spring.dependency-management' version '1.1.7'
|
id 'io.spring.dependency-management' version '1.1.7'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
group = 'com.bernard'
|
group = 'com.bernard'
|
||||||
version = '0.0.1-SNAPSHOT'
|
version = '0.0.1-SNAPSHOT'
|
||||||
|
|
||||||
@ -21,15 +32,33 @@ dependencies {
|
|||||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
|
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.flywaydb:flyway-core'
|
implementation 'org.springframework:spring-jdbc'
|
||||||
implementation 'org.flywaydb:flyway-database-postgresql'
|
implementation 'org.flywaydb:flyway-core:11.3.2'
|
||||||
|
implementation 'org.flywaydb:flyway-database-postgresql:11.3.2'
|
||||||
implementation 'org.springframework.session:spring-session-jdbc'
|
implementation 'org.springframework.session:spring-session-jdbc'
|
||||||
|
implementation 'jakarta.validation:jakarta.validation-api:3.1.1'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-docker-compose'
|
developmentOnly 'org.springframework.boot:spring-boot-docker-compose'
|
||||||
runtimeOnly 'org.postgresql:postgresql'
|
runtimeOnly 'org.postgresql:postgresql'
|
||||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||||
|
|
||||||
|
//Lombok
|
||||||
|
compileOnly 'org.projectlombok:lombok:1.18.36'
|
||||||
|
annotationProcessor 'org.projectlombok:lombok:1.18.36'
|
||||||
|
|
||||||
|
testCompileOnly 'org.projectlombok:lombok:1.18.36'
|
||||||
|
testAnnotationProcessor 'org.projectlombok:lombok:1.18.36'
|
||||||
|
}
|
||||||
|
|
||||||
|
flyway {
|
||||||
|
url = "jdbc:postgresql://127.0.0.1:10051/misael"
|
||||||
|
user = 'misael'
|
||||||
|
password = 'misael-dev'
|
||||||
|
driver = 'org.postgresql.Driver'
|
||||||
|
schemas = ['misael']
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named('test') {
|
tasks.named('test') {
|
||||||
|
|||||||
@ -2,8 +2,8 @@ services:
|
|||||||
postgres:
|
postgres:
|
||||||
image: 'postgres:latest'
|
image: 'postgres:latest'
|
||||||
environment:
|
environment:
|
||||||
- 'POSTGRES_DB=mydatabase'
|
- 'POSTGRES_DB=misael'
|
||||||
- 'POSTGRES_PASSWORD=secret'
|
- 'POSTGRES_PASSWORD=misael-dev'
|
||||||
- 'POSTGRES_USER=myuser'
|
- 'POSTGRES_USER=misael'
|
||||||
ports:
|
ports:
|
||||||
- '5432'
|
- '10051:5432'
|
||||||
|
|||||||
@ -0,0 +1,45 @@
|
|||||||
|
package com.bernard.misael;
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Role;
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
import com.bernard.misael.repository.UserRepository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CustomUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
|
public CustomUserDetailsService(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String pseudo) throws UsernameNotFoundException {
|
||||||
|
User user = userRepository.findByName(pseudo);
|
||||||
|
|
||||||
|
if (user != null) {
|
||||||
|
return new org.springframework.security.core.userdetails.User(user.getName(),
|
||||||
|
user.getPassword(),
|
||||||
|
mapRolesToAuthorities(user.getRoles()));
|
||||||
|
}else{
|
||||||
|
throw new UsernameNotFoundException("Invalid username or password.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection < ? extends GrantedAuthority> mapRolesToAuthorities(Collection<Role> roles) {
|
||||||
|
Collection < ? extends GrantedAuthority> mapRoles = roles.stream()
|
||||||
|
.map(role -> new SimpleGrantedAuthority(role.getName()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return mapRoles;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/main/java/com/bernard/misael/SpringSecurity.java
Normal file
54
src/main/java/com/bernard/misael/SpringSecurity.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package com.bernard.misael;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SpringSecurity {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public static PasswordEncoder passwordEncoder(){
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||||
|
http.csrf().disable()
|
||||||
|
.authorizeHttpRequests((authorize) ->
|
||||||
|
authorize.requestMatchers("/**").permitAll()
|
||||||
|
// .requestMatchers("/index").permitAll()
|
||||||
|
// .requestMatchers("/users").hasRole("ADMIN")
|
||||||
|
).formLogin(
|
||||||
|
form -> form
|
||||||
|
.loginPage("/login")
|
||||||
|
.loginProcessingUrl("/login")
|
||||||
|
.defaultSuccessUrl("/")
|
||||||
|
.permitAll()
|
||||||
|
).logout(
|
||||||
|
logout -> logout
|
||||||
|
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
|
||||||
|
.permitAll()
|
||||||
|
);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
|
auth
|
||||||
|
.userDetailsService(userDetailsService)
|
||||||
|
.passwordEncoder(passwordEncoder());
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/main/java/com/bernard/misael/model/Role.java
Normal file
28
src/main/java/com/bernard/misael/model/Role.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package com.bernard.misael.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Entity
|
||||||
|
@Table(name="roles")
|
||||||
|
public class Role
|
||||||
|
{
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable=false, unique=true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy="roles")
|
||||||
|
private List<User> users;
|
||||||
|
}
|
||||||
37
src/main/java/com/bernard/misael/model/User.java
Normal file
37
src/main/java/com/bernard/misael/model/User.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package com.bernard.misael.model;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Entity
|
||||||
|
@Table(name="users")
|
||||||
|
public class User
|
||||||
|
{
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(nullable=false)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(nullable=false)
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
|
||||||
|
@JoinTable(
|
||||||
|
name="users_roles",
|
||||||
|
joinColumns={@JoinColumn(name="USER_ID", referencedColumnName="ID")},
|
||||||
|
inverseJoinColumns={@JoinColumn(name="ROLE_ID", referencedColumnName="ID")})
|
||||||
|
private List<Role> roles = new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Role;
|
||||||
|
|
||||||
|
public interface RoleRepository extends JpaRepository<Role, Long> {
|
||||||
|
|
||||||
|
Role findByName(String name);
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.bernard.misael.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
|
||||||
|
User findByName(String pseudo);
|
||||||
|
|
||||||
|
}
|
||||||
14
src/main/java/com/bernard/misael/service/UserService.java
Normal file
14
src/main/java/com/bernard/misael/service/UserService.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.bernard.misael.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
import com.bernard.misael.service.dto.UserDto;
|
||||||
|
|
||||||
|
public interface UserService {
|
||||||
|
void saveUser(UserDto userDto);
|
||||||
|
|
||||||
|
User findUserByName(String name);
|
||||||
|
|
||||||
|
List<UserDto> findAllUsers();
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
package com.bernard.misael.service;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.Role;
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
import com.bernard.misael.repository.RoleRepository;
|
||||||
|
import com.bernard.misael.repository.UserRepository;
|
||||||
|
import com.bernard.misael.service.dto.UserDto;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
|
private UserRepository userRepository;
|
||||||
|
private RoleRepository roleRepository;
|
||||||
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
|
public UserServiceImpl(UserRepository userRepository,
|
||||||
|
RoleRepository roleRepository,
|
||||||
|
PasswordEncoder passwordEncoder) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
this.roleRepository = roleRepository;
|
||||||
|
this.passwordEncoder = passwordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveUser(UserDto userDto) {
|
||||||
|
User user = new User();
|
||||||
|
user.setName(userDto.getName());
|
||||||
|
// encrypt the password using spring security
|
||||||
|
user.setPassword(passwordEncoder.encode(userDto.getPassword()));
|
||||||
|
|
||||||
|
Role role = roleRepository.findByName("ROLE_ADMIN");
|
||||||
|
if(role == null){
|
||||||
|
role = checkRoleExist();
|
||||||
|
}
|
||||||
|
user.setRoles(Arrays.asList(role));
|
||||||
|
userRepository.save(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User findUserByName(String name) {
|
||||||
|
return userRepository.findByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserDto> findAllUsers() {
|
||||||
|
List<User> users = userRepository.findAll();
|
||||||
|
return users.stream()
|
||||||
|
.map((user) -> mapToUserDto(user))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserDto mapToUserDto(User user){
|
||||||
|
UserDto userDto = new UserDto();
|
||||||
|
userDto.setName(user.getName());
|
||||||
|
return userDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Role checkRoleExist(){
|
||||||
|
Role role = new Role();
|
||||||
|
role.setName("ROLE_ADMIN");
|
||||||
|
return roleRepository.save(role);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/main/java/com/bernard/misael/service/dto/UserDto.java
Normal file
21
src/main/java/com/bernard/misael/service/dto/UserDto.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.bernard.misael.service.dto;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Email;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserDto
|
||||||
|
{
|
||||||
|
private Long id;
|
||||||
|
@NotEmpty(message = "User name should not be empty")
|
||||||
|
private String name;
|
||||||
|
@NotEmpty(message = "Password should not be empty")
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
81
src/main/java/com/bernard/misael/web/AuthController.java
Normal file
81
src/main/java/com/bernard/misael/web/AuthController.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package com.bernard.misael.web;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
|
||||||
|
import com.bernard.misael.model.User;
|
||||||
|
import com.bernard.misael.service.UserService;
|
||||||
|
import com.bernard.misael.service.dto.UserDto;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class AuthController {
|
||||||
|
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
public AuthController(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/login")
|
||||||
|
public String loginPage() {
|
||||||
|
return "login";
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getLoggedInUser() {
|
||||||
|
if(SecurityContextHolder.getContext().getAuthentication().getPrincipal()
|
||||||
|
instanceof org.springframework.security.core.userdetails.User){
|
||||||
|
org.springframework.security.core.userdetails.User user
|
||||||
|
= (org.springframework.security.core.userdetails.User)
|
||||||
|
SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
return userService.findUserByName(user.getUsername());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index(Model model) {
|
||||||
|
if(SecurityContextHolder.getContext().getAuthentication().getPrincipal() instanceof org.springframework.security.core.userdetails.User){
|
||||||
|
org.springframework.security.core.userdetails.User user
|
||||||
|
= (org.springframework.security.core.userdetails.User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
model.addAttribute("username", user.getUsername());
|
||||||
|
}else{
|
||||||
|
model.addAttribute("username", "no-one");
|
||||||
|
}
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/adduser")
|
||||||
|
public String showRegistrationForm(Model model){
|
||||||
|
// create model object to store form data
|
||||||
|
UserDto user = new UserDto();
|
||||||
|
model.addAttribute("user", user);
|
||||||
|
return "adduser";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/adduser/save")
|
||||||
|
public String registration(@Valid @ModelAttribute("user") UserDto userDto,
|
||||||
|
BindingResult result,
|
||||||
|
Model model){
|
||||||
|
User existingUser = userService.findUserByName("mysaa");
|
||||||
|
|
||||||
|
if(existingUser != null){
|
||||||
|
result.reject("User is already registered");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.hasErrors()){
|
||||||
|
model.addAttribute("user", userDto);
|
||||||
|
return "/adduser";
|
||||||
|
}
|
||||||
|
userService.saveUser(userDto);
|
||||||
|
return "redirect:/adduser?success";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,12 @@
|
|||||||
package com.bernard.misael.web;
|
package com.bernard.misael.web;
|
||||||
|
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import com.bernard.misael.service.dto.UserDto;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
|
||||||
@ -23,11 +28,6 @@ public class QuestionsController {
|
|||||||
public String getForms() {
|
public String getForms() {
|
||||||
return "forms.html";
|
return "forms.html";
|
||||||
}
|
}
|
||||||
@GetMapping("/login")
|
|
||||||
public String loginPage() {
|
|
||||||
return "login.html";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
spring.application.name=Misael
|
|
||||||
spring.session.jdbc.initialize-schema=always
|
|
||||||
27
src/main/resources/application.yml
Normal file
27
src/main/resources/application.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
url: jdbc:mysql://127.0.0.1:10051/misael
|
||||||
|
username: misael
|
||||||
|
password: misael-dev
|
||||||
|
hikari:
|
||||||
|
schema: misael
|
||||||
|
flyway:
|
||||||
|
enabled: true
|
||||||
|
locations: classpath:db/migration/structure, classpath:db/migration/data
|
||||||
|
validate-on-migrate: true
|
||||||
|
default-schema: misael
|
||||||
|
|
||||||
|
# jpa:
|
||||||
|
# properties:
|
||||||
|
# javax:
|
||||||
|
# persistence:
|
||||||
|
# schema-generation:
|
||||||
|
# create-source: metadata
|
||||||
|
# scripts:
|
||||||
|
# action: update
|
||||||
|
# create-target: db-migration.sql
|
||||||
|
# database:
|
||||||
|
# action: none
|
||||||
|
# hibernate:
|
||||||
|
# ddl-auto: none
|
||||||
|
# generate-ddl: true
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
create table roles (id bigint generated by default as identity, name varchar(255) not null, primary key (id));
|
||||||
|
create table users (id bigint generated by default as identity, name varchar(255) not null, password varchar(255) not null, primary key (id));
|
||||||
|
create table users_roles (user_id bigint not null, role_id bigint not null);
|
||||||
|
alter table if exists roles drop constraint if exists UKofx66keruapi6vyqpv6f2or37;
|
||||||
|
alter table if exists roles add constraint UKofx66keruapi6vyqpv6f2or37 unique (name);
|
||||||
|
alter table if exists users_roles add constraint FKj6m8fwv7oqv74fcehir1a9ffy foreign key (role_id) references roles;
|
||||||
|
alter table if exists users_roles add constraint FK2o0jvgh89lemvvo17cbqvdxaa foreign key (user_id) references users;
|
||||||
45
src/main/resources/templates/adduser.html
Normal file
45
src/main/resources/templates/adduser.html
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<div th:replace="~{html-head}"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div th:replace="~{header}"/>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<div th:if="${param.success}">
|
||||||
|
You have successfully registered our app!
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
method="post"
|
||||||
|
role="form"
|
||||||
|
th:action="@{/adduser/save}"
|
||||||
|
th:object="${user}"
|
||||||
|
>
|
||||||
|
<label for="name">Name</label>
|
||||||
|
<input
|
||||||
|
id="name"
|
||||||
|
name="name"
|
||||||
|
placeholder="Enter pseudo"
|
||||||
|
th:field="*{name}"
|
||||||
|
type="text"
|
||||||
|
/>
|
||||||
|
<p th:errors = "*{name}" th:if="${#fields.hasErrors('name')}"></p>
|
||||||
|
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="Enter password"
|
||||||
|
th:field="*{password}"
|
||||||
|
type="password"
|
||||||
|
/>
|
||||||
|
<p th:errors = "*{password}" class="text-danger"
|
||||||
|
th:if="${#fields.hasErrors('password')}"></p>
|
||||||
|
|
||||||
|
<button class="btn btn-primary" type="submit">Register</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -4,7 +4,7 @@
|
|||||||
<ul class="menu">
|
<ul class="menu">
|
||||||
<li><a href="/questions/quizz">Quizz</a></li>
|
<li><a href="/questions/quizz">Quizz</a></li>
|
||||||
<li><a href="/questions/forms">Forms</a></li>
|
<li><a href="/questions/forms">Forms</a></li>
|
||||||
<li><a href="/questions/login">Login</a></li>
|
<li><a href="/login">Login</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
13
src/main/resources/templates/index.html
Normal file
13
src/main/resources/templates/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<div th:replace="~{html-head}"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div th:replace="~{header}"/>
|
||||||
|
<main>
|
||||||
|
Logged in as <div th:text="${username}"></div>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -8,14 +8,24 @@
|
|||||||
<div th:replace="~{header}"/>
|
<div th:replace="~{header}"/>
|
||||||
<main>
|
<main>
|
||||||
|
|
||||||
<form>
|
<div th:if="${param.error}">
|
||||||
<label for="login-pseudo">Pseudo :</label>
|
<div class="alert alert-danger">Invalid Email or Password</div><br/>
|
||||||
<input type="text" id="login-pseudo" name="pseudo"/>
|
</div>
|
||||||
|
<div th:if="${param.logout}">
|
||||||
|
<div class="alert alert-success"> You have been logged out.</div><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form
|
||||||
|
method="post"
|
||||||
|
role="form"
|
||||||
|
th:action="@{/login}">
|
||||||
|
<label for="username">Pseudo :</label>
|
||||||
|
<input type="text" id="username" name="username"/>
|
||||||
<br/>
|
<br/>
|
||||||
<label for="login-password">Mot de passe :</label>
|
<label for="password">Mot de passe :</label>
|
||||||
<input type="text" id="login-password" name="password"/>
|
<input type="password" id="password" name="password"/>
|
||||||
<br/>
|
<br/>
|
||||||
<input id="connect" type="button">Se connecter</input>
|
<input id="connect" type="submit">Se connecter</input>
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user