This commit is contained in:
Viktoria committed 2022-08-31 11:37:17 +02:00
1 parent 2064ed5abc
commit 9efd7b3fb4
33 files changed
+595 -91

No files matched your search

@@ -4,7 +4,6 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class EasyStartupApplication {
@@ -1,50 +1,50 @@
package site.easystartup.web.auth.config;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final DataSource dataSource;
private final PasswordEncoder passwordEncoder;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home", "/registration").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll()
.and()
.rememberMe().userDetailsService(this.userDetailsService())
.rememberMeServices(null)
.tokenValiditySeconds(86400)
.useSecureCookie(true);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder)
.usersByUsernameQuery("SELECT username, password, active FROM usr WHERE username = ?;")
.authoritiesByUsernameQuery("SELECT u.username, ur.roles FROM usr u INNER JOIN user_role ur ON u.id = ur.user_id WHERE username = ?;");
}
}
//package site.easystartup.web.auth.config;
//
//import lombok.RequiredArgsConstructor;
//import org.springframework.beans.factory.annotation.Autowired;
//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.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
//import org.springframework.security.crypto.password.PasswordEncoder;
//
//import javax.sql.DataSource;
//
//@Configuration
//@EnableWebSecurity
//@RequiredArgsConstructor(onConstructor_ = @Autowired)
//public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// private final DataSource dataSource;
//
// private final PasswordEncoder passwordEncoder;
//
// @Override
// protected void configure(HttpSecurity http) throws Exception {
// http
// .authorizeRequests()
// .antMatchers("/", "/home", "/registration").permitAll()
// .anyRequest().authenticated()
// .and()
// .formLogin()
// .loginPage("/login")
// .permitAll()
// .and()
// .logout()
// .permitAll()
// .and()
// .rememberMe().userDetailsService(this.userDetailsService())
// .rememberMeServices(null)
// .tokenValiditySeconds(86400)
// .useSecureCookie(true);
// }
//
// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.jdbcAuthentication()
// .dataSource(dataSource)
// .passwordEncoder(passwordEncoder)
// .usersByUsernameQuery("SELECT username, password, active FROM usr WHERE username = ?;")
// .authoritiesByUsernameQuery("SELECT u.username, ur.roles FROM usr u INNER JOIN user_role ur ON u.id = ur.user_id WHERE username = ?;");
// }
//}
@@ -0,0 +1,72 @@
package site.easystartup.web.auth.controller;
import lombok.RequiredArgsConstructor;
import org.modelmapper.ModelMapper;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import site.easystartup.web.domain.model.User;
import site.easystartup.web.domain.request.LoginRequest;
import site.easystartup.web.domain.request.SignupRequest;
import site.easystartup.web.domain.response.MessageResponse;
import site.easystartup.web.domain.response.SuccessAuthenticationResponse;
import site.easystartup.web.domain.validation.ResponseErrorValidation;
import site.easystartup.web.project.dto.UserDto;
import site.easystartup.web.security.JWTUtil;
import site.easystartup.web.security.SecurityConstants;
import site.easystartup.web.service.AuthService;
import site.easystartup.web.service.UserService;
import javax.validation.Valid;
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
private final JWTUtil jwtUtil;
private final UserService userService;
private final AuthService authService;
private final AuthenticationManager authenticationManager;
private final ResponseErrorValidation responseErrorValidation;
private final ModelMapper modelMapper;
@PostMapping("/signup")
public ResponseEntity<Object> registration(@Valid @RequestBody SignupRequest signupRequest,
BindingResult bindingResult) {
ResponseEntity<Object> errors = responseErrorValidation.mapValidationService(bindingResult);
if (!ObjectUtils.isEmpty(errors)) return errors;
authService.createUser(signupRequest);
return ResponseEntity.ok(new MessageResponse("Account registered successfully!"));
}
@PostMapping("/login")
public ResponseEntity<Object> authentication(@Valid @RequestBody LoginRequest loginRequest,
BindingResult bindingResult) {
ResponseEntity<Object> errors = responseErrorValidation.mapValidationService(bindingResult);
if (!ObjectUtils.isEmpty(errors)) return errors;
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()
));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = SecurityConstants.TOKEN_PREFIX + jwtUtil.generateToken(loginRequest.getUsername());
User user = userService.getUserByUsername(loginRequest.getUsername());
SuccessAuthenticationResponse response = new SuccessAuthenticationResponse(jwt, modelMapper.map(user, UserDto.class));
return ResponseEntity.ok().body(response);
}
}
@@ -0,0 +1,19 @@
package site.easystartup.web.domain.annotation;
import site.easystartup.web.domain.validation.PasswordMatchesValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordMatchesValidator.class)
@Documented
public @interface PasswordMatches {
String message() default "Password do not match";
Class<?>[] groups() default{};
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,11 @@
package site.easystartup.web.domain.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.BAD_REQUEST)
public class UserExistException extends RuntimeException {
public UserExistException(String message) {
super(message);
}
}
@@ -1,5 +1,11 @@
package site.easystartup.web.domain.model;
public enum Role {
USER, PREMIUM, MODER, ADMIN;
USER("USER"), PREMIUM("PREMIUM"), MODER("MODER"), ADMIN("ADMIN");
private String role;
Role(String role) {
this.role = role;
}
}
@@ -2,12 +2,13 @@ package site.easystartup.web.domain.model;
import lombok.*;
import org.hibernate.Hibernate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import site.easystartup.web.project.domain.model.Participant;
import javax.persistence.*;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.*;
@Getter
@Setter
@@ -15,7 +16,7 @@ import java.util.Set;
@RequiredArgsConstructor
@Entity
@Table(name = "usr")
public class User {
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_id")
@@ -75,4 +76,31 @@ public class User {
if (roles.contains(Role.PREMIUM) || roles.contains(Role.ADMIN)) return true;
return false;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new ArrayList<>();
getRoles().forEach(role -> authorities.add(new SimpleGrantedAuthority(role.name())));
return authorities;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@@ -0,0 +1,14 @@
package site.easystartup.web.domain.request;
import lombok.Data;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
@Data
public class LoginRequest {
@NotEmpty(message = "Username cannot be empty")
private String username;
@NotEmpty(message = "Password cannot be empty")
private String password;
}
@@ -0,0 +1,31 @@
package site.easystartup.web.domain.request;
import lombok.Data;
import site.easystartup.web.domain.annotation.PasswordMatches;
import site.easystartup.web.domain.model.Role;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.util.Set;
@Data
@PasswordMatches
public class SignupRequest {
@NotEmpty
@Size(min = 3, max = 30, message = "Username should be no less 3 and no more 30 signs")
private String username;
@Email(message = "It should have email format")
@NotBlank(message = "Email is required")
private String email;
@NotEmpty(message = "Password is required")
@Size(min = 6, max = 30, message = "Password should be no less 6 and no more 30 signs")
private String password;
private String confirmPassword;
private Set<String> roles;
}
@@ -0,0 +1,15 @@
package site.easystartup.web.domain.response;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
public class InvalidLoginResponse {
private String username;
private String password;
public InvalidLoginResponse() {
this.username = "Invalid username";
this.password = "Invalid password";
}
}
@@ -3,10 +3,10 @@ package site.easystartup.web.domain.response;
import lombok.Data;
@Data
public class ResponseMessage {
public class MessageResponse {
private String message;
public ResponseMessage(String message) {
public MessageResponse(String message) {
this.message = message;
}
}
@@ -0,0 +1,12 @@
package site.easystartup.web.domain.response;
import lombok.AllArgsConstructor;
import lombok.Getter;
import site.easystartup.web.project.dto.UserDto;
@Getter
@AllArgsConstructor
public class SuccessAuthenticationResponse {
private String jwt;
private UserDto userDto;
}
@@ -0,0 +1,21 @@
package site.easystartup.web.domain.validation;
import site.easystartup.web.domain.annotation.PasswordMatches;
import site.easystartup.web.domain.request.SignupRequest;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> {
@Override
public void initialize(PasswordMatches constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
SignupRequest signupRequest = (SignupRequest) o;
return signupRequest.getPassword().equals(signupRequest.getConfirmPassword());
}
}
@@ -6,17 +6,13 @@ import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import site.easystartup.web.domain.model.User;
import site.easystartup.web.domain.response.ResponseMessage;
import site.easystartup.web.domain.response.MessageResponse;
import site.easystartup.web.domain.validation.ResponseErrorValidation;
import site.easystartup.web.forum.domain.model.Discussion;
import site.easystartup.web.forum.domain.model.DiscussionMessage;
import site.easystartup.web.forum.domain.model.DiscussionStatus;
import site.easystartup.web.forum.domain.model.Topic;
import site.easystartup.web.forum.domain.request.DiscussionMessageRequest;
import site.easystartup.web.forum.domain.request.DiscussionRequest;
@@ -25,10 +21,7 @@ import site.easystartup.web.forum.dto.DiscussionDto;
import site.easystartup.web.forum.dto.DiscussionMessageDto;
import site.easystartup.web.forum.dto.TopicDto;
import site.easystartup.web.forum.service.ForumService;
import site.easystartup.web.forum.repo.TopicRepo;
import site.easystartup.web.project.domain.model.Project;
import site.easystartup.web.project.domain.requst.ProjectRequest;
import site.easystartup.web.project.dto.ProjectDto;
import site.easystartup.web.service.UserService;
import javax.validation.Valid;
@@ -151,9 +144,9 @@ public class ForumController {
DiscussionMessage message = forumService.getDiscussionMessageById(message_id);
User user = userService.getUserByPrincipal(principal);
if(!(message.getSender().equals(user.getUsername()) || user.isModer()))
return ResponseEntity.ok(new ResponseMessage("No permissions!"));
return ResponseEntity.ok(new MessageResponse("No permissions!"));
forumService.deleteDiscussionMessage(message_id, user);
return ResponseEntity.ok(new ResponseMessage("Message was deleted!"));
return ResponseEntity.ok(new MessageResponse("Message was deleted!"));
}
@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.*;
import site.easystartup.web.project.domain.model.Project;
import site.easystartup.web.project.domain.requst.ParticipantRequest;
import site.easystartup.web.project.domain.requst.ProjectRequest;
import site.easystartup.web.domain.response.ResponseMessage;
import site.easystartup.web.domain.response.MessageResponse;
import site.easystartup.web.domain.validation.ResponseErrorValidation;
import site.easystartup.web.project.dto.ParticipantDto;
import site.easystartup.web.project.dto.ProjectDto;
@@ -55,7 +55,7 @@ public class ProjectController {
public ResponseEntity<Object> deleteProject(@PathVariable("projectId") Long projectId,
Principal principal) {
projectService.deleteProject(projectId, principal);
return ResponseEntity.ok(new ResponseMessage("Project was deleted!"));
return ResponseEntity.ok(new MessageResponse("Project was deleted!"));
}
@GetMapping("/{projectId}")
@@ -41,7 +41,7 @@ public class Project {
private int commercialStatus;
@ManyToMany
@JoinTable(
@JoinTable(name = "project_tag",
joinColumns = @JoinColumn(name = "project_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
@@ -1,23 +1,25 @@
package site.easystartup.web.project.dto;
import lombok.Data;
import lombok.NoArgsConstructor;
import site.easystartup.web.domain.model.Role;
import java.io.Serializable;
import java.util.Set;
@Data
@NoArgsConstructor
public class UserDto implements Serializable {
private final long id;
private final String username;
private final String password;
private final boolean active;
private final String full_name;
private final String status;
private final String iconPath;
private final String email;
private final Set<String> tags;
private final Set<String> professions;
private final Set<Long> projects;
private final Set<Role> roles;
private long id;
private String username;
private String password;
private boolean active;
private String full_name;
private String status;
private String iconPath;
private String email;
private Set<String> tags;
private Set<String> professions;
private Set<Long> projects;
private Set<Role> roles;
}
@@ -11,6 +11,6 @@ import java.util.LinkedHashSet;
@Repository
public interface ParticipantRepo extends JpaRepository<Participant, Long> {
@Query ("SELECT Project FROM Participant WHERE nameOfPosition = :nameOfPosition")
@Query ("SELECT p FROM Participant p WHERE p.nameOfPosition = :nameOfPosition")
LinkedHashSet<Project> findAllByNameOfPosition(@Param("nameOfPosition") String name);
}
@@ -6,6 +6,7 @@ import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import site.easystartup.web.domain.model.User;
import site.easystartup.web.project.domain.model.Project;
import site.easystartup.web.project.domain.model.Tag;
import java.util.List;
@@ -13,9 +14,7 @@ import java.util.List;
public interface ProjectRepo extends JpaRepository<Project, Long> {
List<Project> findAllByOwnerOrderByCreatedDate(User owner);
@Query("SELECT p from Project p WHERE p.technology LIKE %:technology%")
List<Project> findAllByTechnology(@Param("technology") String tech);
List<Project> findAllByTechnology(Tag tag);
List<Project> findAllByCommercialStatusOrderByCreatedDateAsc(int commercialStatus);
@@ -66,7 +66,7 @@ public class ProjectService {
}
public List<Project> getAllProjectsWithTechnology(String technology) {
return projectRepo.findAllByTechnology(technology.trim());
return projectRepo.findAllByTechnology(tagService.getTechnologyByName(technology.trim()));
}
public List<Project> getAllProjectsForCurrentUser(Principal principal) {
@@ -31,4 +31,8 @@ public class TagService {
});
return tags;
}
public Tag getTechnologyByName(String tag) {
return tagRepo.findTagByTagNameIgnoreCase(tag).orElseThrow(() -> new RuntimeException("Technolohy not found"));
}
}
@@ -3,6 +3,10 @@ package site.easystartup.web.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import site.easystartup.web.domain.model.User;
import java.util.Optional;
public interface UserRepo extends JpaRepository<User, Long> {
User findByUsername(String username);
Optional<User> findUserByUsername(String username);
}
@@ -0,0 +1,25 @@
package site.easystartup.web.security;
import com.google.gson.Gson;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import site.easystartup.web.domain.response.InvalidLoginResponse;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JWTAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException, ServletException {
InvalidLoginResponse invalidLoginResponse = new InvalidLoginResponse();
String jsonLoginResponse = new Gson().toJson(invalidLoginResponse);
response.setContentType(SecurityConstants.HEADER_STRING);
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().println(jsonLoginResponse);
}
}
@@ -0,0 +1,56 @@
package site.easystartup.web.security;
import com.auth0.jwt.exceptions.JWTVerificationException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import site.easystartup.web.service.CustomUserDetailService;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@RequiredArgsConstructor
public class JWTFilter extends OncePerRequestFilter {
private final JWTUtil jwtUtil;
private final CustomUserDetailService userDetailService;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String header = request.getHeader(SecurityConstants.HEADER_STRING);
if (StringUtils.hasText(header) && header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
String jwt = header.split(" ")[1];
if (jwt.isEmpty()) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid JWT token in Bearer Header");
} else {
try {
String email = jwtUtil.validateTokenAndRetrieveClaim(jwt);
UserDetails userDetails = userDetailService.loadUserByUsername(email);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userDetails,
userDetails.getPassword(),
userDetails.getAuthorities());
if (SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
} catch (JWTVerificationException ex) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST, " Invalid JWT token");
}
}
}
filterChain.doFilter(request, response);
}
}
@@ -0,0 +1,37 @@
package site.easystartup.web.security;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.stereotype.Component;
import java.time.ZonedDateTime;
import java.util.Date;
@Component
public class JWTUtil {
public String generateToken(String username) {
Date expirationDate = Date.from(ZonedDateTime.now().plusDays(30).toInstant());
return JWT.create()
.withSubject("User details")
.withClaim("username", username)
.withIssuedAt(Date.from(ZonedDateTime.now().toInstant()))
.withIssuer("site.easystartup")
.withExpiresAt(expirationDate)
.sign(Algorithm.HMAC256(SecurityConstants.SECRET));
}
public String validateTokenAndRetrieveClaim(String token) throws JWTVerificationException {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SecurityConstants.SECRET))
.withSubject("User details")
.withIssuer("site.easystartup")
.build();
DecodedJWT decodedJWT = verifier.verify(token);
return decodedJWT.getClaim("username").asString();
}
}
@@ -0,0 +1,60 @@
package site.easystartup.web.security;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import site.easystartup.web.service.CustomUserDetailService;
@EnableWebSecurity
@RequiredArgsConstructor
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final CustomUserDetailService customUserDetailService;
private final JWTAuthenticationEntryPoint jwtAuthenticationEntryPoint;
private final JWTFilter jwtFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailService).passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers(SecurityConstants.SIGN_UP_URLS).permitAll()
// .antMatchers("/").permitAll();
.anyRequest().authenticated();
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
@@ -0,0 +1,13 @@
package site.easystartup.web.security;
public class SecurityConstants {
public static final String SIGN_UP_URLS = "/api/auth/*";
public static final String SECRET = "SecretKeyGenJWT";
public static final String TOKEN_PREFIX = "Bearer ";
public static final String HEADER_STRING = "Authorization";
public static final String CONTENT_TYPE = "application/json";
// public static final long EXPIRATION_TIME = 600_000_000; //10min
public static final long EXPIRATION_TIME = Long.MAX_VALUE;
}
@@ -0,0 +1,36 @@
package site.easystartup.web.service;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import site.easystartup.web.domain.exception.UserExistException;
import site.easystartup.web.domain.model.Role;
import site.easystartup.web.domain.model.User;
import site.easystartup.web.domain.request.SignupRequest;
import site.easystartup.web.repo.UserRepo;
import java.util.HashSet;
import java.util.Set;
@Service
@RequiredArgsConstructor
public class AuthService {
private final UserRepo userRepo;
private final PasswordEncoder passwordEncoder;
public User createUser(SignupRequest signupRequest) {
if (userRepo.findUserByUsername(signupRequest.getUsername()).isPresent()) {
throw new UserExistException("An account with this username already exists.");
}
User user = new User();
user.setEmail(signupRequest.getEmail());
user.setUsername(signupRequest.getUsername());
user.setPassword(passwordEncoder.encode(signupRequest.getPassword()));
Set<Role> roles = new HashSet<>();
signupRequest.getRoles().forEach(role -> roles.add(Role.valueOf(role)));
user.setRoles(roles);
return userRepo.save(user);
}
}
@@ -0,0 +1,39 @@
package site.easystartup.web.service;
import lombok.RequiredArgsConstructor;
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 site.easystartup.web.domain.model.User;
import site.easystartup.web.repo.UserRepo;
import java.util.ArrayList;
import java.util.Collection;
@Service
@RequiredArgsConstructor
public class CustomUserDetailService implements UserDetailsService {
private final UserRepo userRepo;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepo.findUserByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
user.getRoles().forEach(role -> {
authorities.add(new SimpleGrantedAuthority(role.name()));
});
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
}
public UserDetails loadUserById(Long userId) {
User user = userRepo.findById(userId)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
return user;
}
}
@@ -22,4 +22,8 @@ public class UserService {
public User getUserById(Long userId) {
return userRepo.findById(userId).orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
public User getUserByUsername(String username) {
return userRepo.findUserByUsername(username).orElseThrow(() -> new UsernameNotFoundException("User not found"));
}
}
@@ -1,11 +1,12 @@
package site.easystartup.web.storage.service;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
@Service
public interface StorageService {
void init();
void save(MultipartFile file);