Skip to content

Commit

Permalink
lesson 1.12 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kleislicat committed Aug 26, 2024
1 parent f2caba5 commit 60ee12c
Show file tree
Hide file tree
Showing 9 changed files with 293 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@EnableJpaRepositories("com.example.demo.model.persistence.repositories")
@EntityScan("com.example.demo.model.persistence")
@SpringBootApplication
@SpringBootApplication(exclude = {SecurityAutoConfiguration.class})
public class SareetaApplication {

@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
public static void main(String[] args) {
SpringApplication.run(SareetaApplication.class, args);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,61 @@
package com.example.demo.controllers;

import java.util.Optional;

import com.example.demo.model.persistence.Cart;
import com.example.demo.model.persistence.User;
import com.example.demo.model.persistence.repositories.CartRepository;
import com.example.demo.model.persistence.repositories.UserRepository;
import com.example.demo.model.requests.CreateUserRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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 com.example.demo.model.persistence.Cart;
import com.example.demo.model.persistence.User;
import com.example.demo.model.persistence.repositories.CartRepository;
import com.example.demo.model.persistence.repositories.UserRepository;
import com.example.demo.model.requests.CreateUserRequest;

@RestController
@RequestMapping("/api/user")
public class UserController {

@Autowired
private UserRepository userRepository;

@Autowired
private CartRepository cartRepository;

@GetMapping("/id/{id}")
public ResponseEntity<User> findById(@PathVariable Long id) {
return ResponseEntity.of(userRepository.findById(id));
}

@GetMapping("/{username}")
public ResponseEntity<User> findByUserName(@PathVariable String username) {
User user = userRepository.findByUsername(username);
return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user);
}

@PostMapping("/create")
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest createUserRequest) {
User user = new User();
user.setUsername(createUserRequest.getUsername());
Cart cart = new Cart();
cartRepository.save(cart);
user.setCart(cart);
userRepository.save(user);
return ResponseEntity.ok(user);
}



@Autowired
private UserRepository userRepository;

@Autowired
private CartRepository cartRepository;

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@GetMapping("/id/{id}")
public ResponseEntity<User> findById(@PathVariable Long id) {
return ResponseEntity.of(userRepository.findById(id));
}

@GetMapping("/{username}")
public ResponseEntity<User> findByUserName(@PathVariable String username) {
User user = userRepository.findByUsername(username);
return user == null ? ResponseEntity.notFound().build() : ResponseEntity.ok(user);
}

@PostMapping("/create")
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest createUserRequest) {

User user = new User();
user.setUsername(createUserRequest.getUsername());
Cart cart = new Cart();
cartRepository.save(cart);

user.setCart(cart);
if (createUserRequest.getPassword().length() < 7 ||
!createUserRequest.getPassword().equals(createUserRequest.getConfirmPassword())) {
return ResponseEntity.badRequest().build();
}
user.setPassword(bCryptPasswordEncoder.encode(createUserRequest.getPassword()));
userRepository.save(user);
return ResponseEntity.ok(user);
}

}
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
package com.example.demo.model.persistence;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;

import javax.persistence.*;


@Entity
@Table(name = "user")
Expand All @@ -26,7 +18,17 @@ public class User {
@Column(nullable = false, unique = true)
@JsonProperty
private String username;


@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
@Column(nullable = false)
private String password;
public String getPassword(){
return password;
}
public void setPassword(String password) {
this.password = password;
}

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "cart_id", referencedColumnName = "id")
@JsonIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,32 @@ public class CreateUserRequest {
@JsonProperty
private String username;

@JsonProperty
private String password;

@JsonProperty
private String confirmPassword;

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public void setPassword(String password) {
this.password = password;
}

public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
}
public String getPassword() {
return password;
}

public String getConfirmPassword() {
return confirmPassword;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.example.demo.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.auth0.jwt.JWT;
import com.example.demo.model.persistence.User;
import com.fasterxml.jackson.databind.ObjectMapper;

import static com.auth0.jwt.algorithms.Algorithm.HMAC512;

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

private AuthenticationManager authenticationManager;

public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}

@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
try {
User credentials = new ObjectMapper()
.readValue(req.getInputStream(), User.class);

return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
credentials.getUsername(),
credentials.getPassword(),
new ArrayList<>()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {

String token = JWT.create()
.withSubject(((org.springframework.security.core.userdetails.User) auth.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + SecurityConstants.EXPIRATION_TIME))
.sign(HMAC512(SecurityConstants.SECRET.getBytes()));
res.addHeader(SecurityConstants.HEADER_STRING, SecurityConstants.TOKEN_PREFIX + token);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.example.demo.security;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

import com.auth0.jwt.JWT;

import static com.auth0.jwt.algorithms.Algorithm.HMAC512;

@Component
public class JWTAuthenticationVerficationFilter extends BasicAuthenticationFilter {

public JWTAuthenticationVerficationFilter(AuthenticationManager authManager) {
super(authManager);
}

@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
throws IOException, ServletException {
String header = req.getHeader(SecurityConstants.HEADER_STRING);

if (header == null || !header.startsWith(SecurityConstants.TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}

UsernamePasswordAuthenticationToken authentication = getAuthentication(req);

SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}

private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req) {
String token = req.getHeader(SecurityConstants.HEADER_STRING);
if (token != null) {
String user = JWT.require(HMAC512(SecurityConstants.SECRET.getBytes())).build()
.verify(token.replace(SecurityConstants.TOKEN_PREFIX, ""))
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.demo.security;

public class SecurityConstants {

public static final String SECRET = "oursecretkey";
public static final long EXPIRATION_TIME = 864_000_000; // 10 days
public static final String TOKEN_PREFIX = "Bearer ";
public static final String HEADER_STRING = "Authorization";
public static final String SIGN_UP_URL = "/api/user/create";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.example.demo.security;

import java.util.Collections;

import org.springframework.beans.factory.annotation.Autowired;
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.example.demo.model.persistence.User;
import com.example.demo.model.persistence.repositories.UserRepository;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

@Autowired
private UserRepository userRepository;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), Collections.emptyList());
}
}
Loading

0 comments on commit 60ee12c

Please sign in to comment.