Home > Back-end >  User is in database, but it still lets him register unlimited amount of times
User is in database, but it still lets him register unlimited amount of times

Time:10-31

While there is user in the database, another user with exactly the same credentials is "successfully" inserted in the database...

Hello! I'm building my own ecommerce app and I included spring security. Now, while I was developing security part of the app, I tried it to see if it's working and once I entered desired info in the request body, for the first request the user was successfully inserted in the database, but when I tried to do it the second time, to check if the userExists which throws and error that user is already registered, works, it just added another user with the same credentials (name, lastname, mail and so). I go to userRepository to check if there is already the user with the same email, it makes sense what i wrote, but it doesnt work...Please help...Here are all the files:


EDIT : Mistakenly copied UserRegistrationController twice...So here is the userService.java:

package com.marin.thrift.service;

import com.marin.thrift.dao.UserRepository;
import com.marin.thrift.entity.User;
import lombok.AllArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Service
@AllArgsConstructor
public class UserService implements UserDetailsService {

    private final UserRepository userRepository;
    private final static String USER_NOT_FOUND = "user with email %s not found";
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        return userRepository.findByUsername(email).orElseThrow(()-> new UsernameNotFoundException(String.format(USER_NOT_FOUND, email)));
    }

    public String singUpUser(User user){
        boolean userExists = userRepository.findByUsername(user.getEmail()).isPresent();

        if(userExists){
            return "user already in place";
        }

        String encodedPassword = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);

        userRepository.save(user);

        return "it works";
    }
}

package com.marin.thrift.registration;

import lombok.AllArgsConstructor;
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;

@RestController
@RequestMapping(path = "api/v1/registration")
@AllArgsConstructor
public class UserRegistrationController {

    private RegistrationService registrationService;

    @PostMapping
    public String register(@RequestBody registrationRequest request){
        return registrationService.register(request);
    }

}
package com.marin.thrift.registration;

import lombok.AllArgsConstructor;
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;

@RestController
@RequestMapping(path = "api/v1/registration")
@AllArgsConstructor
public class UserRegistrationController {

    private RegistrationService registrationService;

    @PostMapping
    public String register(@RequestBody registrationRequest request){
        return registrationService.register(request);
    }

}
package com.marin.thrift.registration;

import com.marin.thrift.entity.Role;
import com.marin.thrift.entity.User;
import com.marin.thrift.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@AllArgsConstructor
public class RegistrationService {

    private final EmailValidator emailValidator;
    private final UserService userService;

    public String register(registrationRequest request) {
        Boolean isValidEmail = emailValidator.test(request.getEmail());

        if (!isValidEmail){
            throw new IllegalStateException("Email is not valid");
        }

        return userService.singUpUser(new User(request.getFirstName(), request.getLastName(),
                request.getPassword(),  request.getEmail(),  Role.USER));
    }
}
package com.marin.thrift.entity;

import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import java.util.Collection;
import java.util.Date;

@Entity
@Data
@Table(name = "users")
public class User implements UserDetails {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "date_of_birth")
    private Date dateOfBirth;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    @Column(name = "email")
    private String email;
    private Role role;
    private Boolean locked = false;
    private Boolean enabled = false;

    public User(String firstName, String lastName, String password, String email, Role role) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.password = password;
        this.email = email;
        this.role = role;
    }

    public User() {

    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.name());
        return null;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public String getUsername(){
        return email;
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return !locked;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return enabled;
    }
}
package com.marin.thrift.security.config;

import com.marin.thrift.service.UserService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
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.bcrypt.BCryptPasswordEncoder;

@Configuration
@AllArgsConstructor
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private final UserService userService;
    private final BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.csrf()
                .disable().authorizeRequests()
                    .antMatchers("/api/v*/registration/**").permitAll()
                        .anyRequest().authenticated().and().formLogin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.authenticationProvider(daoAuthenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider(){
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();

        provider.setPasswordEncoder(bCryptPasswordEncoder);
        provider.setUserDetailsService(userService);

        return provider;
    }
}
package com.marin.thrift.registration;

import lombok.*;

@Getter
@AllArgsConstructor
@EqualsAndHashCode
@ToString
public class registrationRequest {

    private final String firstName;
    private final String lastName;
    private final String password;
    private final String email;
}

CodePudding user response:

Without UserService it's hard to say what is happen. But if I see your jpa mapping I can guess that if you want unique entry per unique user, you have to delete generated column id. And instead you have to put @Id annotation on email. In this case you need also make changes in sql table. Or as alternative you can stay by current mapping and simply conduct findByEmail before save entity. And if Optional is not empty - then user is already in database registred.

CodePudding user response:

I just fixed my mistake. The mistake was in the database where I forgot to set email as unique. Once I did that, the code works perfectly... Thank you to everyone who went out of their way to help me :) Happy coding :D <3

  • Related