Skip to content

Commit

Permalink
Merge pull request #92 from JimTheCat/CU-8696y76jy_EPIC---API-v3_King…
Browse files Browse the repository at this point in the history
…a-Traczyk

Cu 8696y76jy epic   api v3 kinga traczyk
  • Loading branch information
KinTrae authored Dec 27, 2024
2 parents c543d96 + 8c742a4 commit c12287e
Show file tree
Hide file tree
Showing 29 changed files with 368 additions and 223 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ Engineering Thesis
For production environment, you need to have an oracle database.
If you don't have a created an oracle database yet, run script `database/install.sql`.


## Profiles
`swagger` - to run application with Swagger
`swagger` - to run application with Swagger
`dev` - to run application with H2 database (for offline development)

## Swagger
To run swagger use `swagger` profile.
Link to swagger documentation: http://localhost:8080/swagger-ui/index.html

## Offline development && Testing
To develop application offline please use `dev` profile - it uses h2 database instead of oracle database that is used on production.
<img alt="img.png" height="300" src="img.png" width="500"/>
No other configurations are needed.

## Environment variables
`DB_URL` - database url
`DB_USERNAME` - database username
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@
import meowhub.backend.posts.services.PostService;
import meowhub.backend.shared.constants.AlertConstants;
import meowhub.backend.users.dtos.BasicUserInfoDto;
import meowhub.backend.users.facades.UserPostServiceFacade;
import meowhub.backend.users.models.User;
import meowhub.backend.posts.repositories.PostRepository;
import meowhub.backend.users.repositories.UserRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.webjars.NotFoundException;

Expand All @@ -21,8 +20,8 @@
@Service
@RequiredArgsConstructor
public class PostServiceImpl implements PostService {
private final UserPostServiceFacade userPostServiceFacade;
private final PostRepository postRepository;
private final UserRepository userRepository;

@Override
public Page<PostDto> getPosts(String requestedBy, int pageNo, int pageSize) {
Expand All @@ -33,8 +32,7 @@ public Page<PostDto> getPosts(String requestedBy, int pageNo, int pageSize) {
@Override
public Page<PostDto> getPostsForUser(String login, String requestedBy, int pageNo, int pageSize) {
Pageable pageable = PageRequest.of(pageNo, pageSize);
userRepository.findByLogin(login)
.orElseThrow(() -> new UsernameNotFoundException(String.format(AlertConstants.USER_WITH_LOGIN_NOT_FOUND, login)));
userPostServiceFacade.validateIfUserExists(login);

if (login.equals(requestedBy)) {
return postRepository.findOwn(login, pageable);
Expand All @@ -45,8 +43,7 @@ public Page<PostDto> getPostsForUser(String login, String requestedBy, int pageN

@Override
public PostDto createPost(String login, String content) {
User postOwner = userRepository.findByLogin(login)
.orElseThrow(() -> new UsernameNotFoundException(String.format(AlertConstants.USER_WITH_LOGIN_NOT_FOUND, login)));
User postOwner = userPostServiceFacade.findUserByLogin(login);
Post post = new Post();
post.setContentHtml(content);
post.setUser(postOwner);
Expand All @@ -69,8 +66,7 @@ public void deletePost(String login, String postId) {
}

private Post findUserPost(String login, String postId) {
userRepository.findByLogin(login)
.orElseThrow(() -> new UsernameNotFoundException(String.format(AlertConstants.USER_WITH_LOGIN_NOT_FOUND, login)));
userPostServiceFacade.validateIfUserExists(login);

return postRepository.findByUserLoginAndId(login, postId)
.orElseThrow(() -> new NotFoundException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "post", "id", postId)));
Expand All @@ -81,9 +77,7 @@ private PostDto convertToPostDto(Post post) {
return null;
}

String login = post.getUser().getLogin();
BasicUserInfoDto author = userRepository.findBasicUserInfoByLogin(login)
.orElseThrow(() -> new UsernameNotFoundException(String.format(AlertConstants.USER_WITH_LOGIN_NOT_FOUND, login)));
BasicUserInfoDto author = userPostServiceFacade.getBasicUserInfo(post.getUser().getLogin());

return PostDto.builder()
.id(post.getId())
Expand Down
66 changes: 7 additions & 59 deletions backend/src/main/java/meowhub/backend/security/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
package meowhub.backend.security;

import meowhub.backend.constants.Genders;
import meowhub.backend.constants.PrivacySettings;
import meowhub.backend.constants.Roles;
import meowhub.backend.users.models.Gender;
import meowhub.backend.users.models.PrivacySetting;
import meowhub.backend.users.models.Role;
import meowhub.backend.users.models.User;
import meowhub.backend.users.repositories.PrivacySettingRepository;
import meowhub.backend.users.repositories.GenderRepository;
import meowhub.backend.users.repositories.RoleRepository;
import meowhub.backend.users.repositories.UserRepository;
import meowhub.backend.users.facades.UserAuthServiceFacade;
import meowhub.backend.security.jwt.AuthEntryPointJwt;
import meowhub.backend.security.jwt.AuthTokenFilter;
import org.springframework.boot.CommandLineRunner;
Expand All @@ -28,7 +20,6 @@
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Configuration
@EnableWebSecurity
Expand Down Expand Up @@ -60,59 +51,16 @@ SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http, AuthEntryPoint
}

@Bean
public CommandLineRunner initData(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder, PrivacySettingRepository privacySettingRepository, GenderRepository genderRepository) {
public CommandLineRunner initData(UserAuthServiceFacade userAuthServiceFacade) {
return args -> {
Role userRole = roleRepository.findByCode(Roles.ROLE_USER.name())
.orElseGet(() -> roleRepository.save(new Role(Roles.ROLE_USER)));
Role adminRole = roleRepository.findByCode(Roles.ROLE_ADMIN.name())
.orElseGet(() -> roleRepository.save(new Role(Roles.ROLE_ADMIN)));

PrivacySetting publicSetting = privacySettingRepository.findByCode(PrivacySettings.PUBLIC.name())
.orElseGet(() -> privacySettingRepository.save(new PrivacySetting(PrivacySettings.PUBLIC)));

Gender female = genderRepository.findByCode(Genders.FEMALE.name())
.orElseGet(() -> genderRepository.save(new Gender(Genders.FEMALE)));

if (!userRepository.existsByLogin("user1")) {
User user1 = new User();
user1.setLogin("user1");
user1.setPassword(passwordEncoder.encode("password1"));
user1.setEmail("[email protected]");
user1.setName("Jan");
user1.setSurname("Kos");
user1.setSalt("salt");
user1.setAccountNonLocked(false);
user1.setBirthdate(LocalDate.of(1990, 1, 1));
user1.setCredentialsNonExpired(true);
user1.setCredentialsExpiryDate(LocalDateTime.now().plusYears(1));
user1.setRole(userRole);
user1.setPostsPrivacy(publicSetting);
user1.setFriendsPrivacy(publicSetting);
user1.setProfilePrivacy(publicSetting);
user1.setGender(female);
userRepository.save(user1);
if (!userAuthServiceFacade.existsByLogin("user1")) {
userAuthServiceFacade.createUser("user1", "Gustaw", "Jeleń", "[email protected]", "userPass", LocalDate.of(1970, 10, 14), Roles.ROLE_USER, Genders.MALE);
}

if (!userRepository.existsByLogin("admin")) {
User admin = new User();
admin.setLogin("admin");
admin.setPassword(passwordEncoder.encode("adminPass"));
admin.setEmail("[email protected]");
admin.setName("Gustaw");
admin.setSurname("Jeleń");
admin.setSalt("salt");
admin.setAccountNonLocked(false);
admin.setBirthdate(LocalDate.of(1980, 1, 1));
admin.setCredentialsNonExpired(true);
admin.setCredentialsExpiryDate(LocalDateTime.now().plusYears(1));
admin.setRole(adminRole);
admin.setPostsPrivacy(publicSetting);
admin.setFriendsPrivacy(publicSetting);
admin.setProfilePrivacy(publicSetting);
admin.setGender(female);
userRepository.save(admin);
}
if (!userAuthServiceFacade.existsByLogin("admin")) {
userAuthServiceFacade.createUser("admin", "Jan", "Kos", "[email protected]", "adminPass", LocalDate.of(1979, 12, 11), Roles.ROLE_ADMIN, Genders.MALE);

}
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import lombok.RequiredArgsConstructor;
import meowhub.backend.dtos.UserDto;
import meowhub.backend.users.services.UserService;
import meowhub.backend.users.facades.UserAdminServiceFacade;
import org.springframework.http.ResponseEntity;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
Expand All @@ -17,24 +16,17 @@
@RequestMapping("/api/admin")
@RequiredArgsConstructor
public class AdminController {
private final UserService userService;
private final UserAdminServiceFacade userAdminServiceFacade;

@GetMapping("/all-users")
public ResponseEntity<List<UserDto>> getAllUsers() {
List<UserDto> allUsers = userService.getAllUsers();
List<UserDto> allUsers = userAdminServiceFacade.getAllUsers();
return ResponseEntity.ok(allUsers);
}

@PostMapping("/user/change-role")
public ResponseEntity<String> changeUserRole(@RequestParam String userId, @RequestParam String roleName) {
userService.changeUserRole(userId, roleName);
userAdminServiceFacade.changeUserRole(userId, roleName);
return ResponseEntity.ok("Role updated");
}

@GetMapping("/user/{userId}")
public ResponseEntity<UserDto> getUserById(@PathVariable String userId) {
UserDto user = userService.getUserById(userId);
return ResponseEntity.ok(user);
}

}
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
package meowhub.backend.security.services.impl;

import lombok.RequiredArgsConstructor;
import meowhub.backend.constants.PrivacySettings;
import meowhub.backend.constants.Roles;
import meowhub.backend.shared.constants.AlertConstants;
import meowhub.backend.shared.exceptions.NotUniqueObjectException;
import meowhub.backend.users.models.Gender;
import meowhub.backend.users.models.PrivacySetting;
import meowhub.backend.users.models.Role;
import meowhub.backend.users.models.User;
import meowhub.backend.users.repositories.GenderRepository;
import meowhub.backend.users.repositories.PrivacySettingRepository;
import meowhub.backend.users.repositories.RoleRepository;
import meowhub.backend.users.repositories.UserRepository;
import meowhub.backend.users.facades.UserAuthServiceFacade;
import meowhub.backend.security.jwt.JwtUtils;
import meowhub.backend.security.requests.LoginRequest;
import meowhub.backend.security.requests.SignUpRequest;
Expand All @@ -26,7 +18,6 @@
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
Expand All @@ -36,11 +27,7 @@
public class AuthServiceImpl implements AuthService {
private final JwtUtils jwtUtils;
private final AuthenticationManager authenticationManager;
private final UserRepository userRepository;
private final RoleRepository roleRepository;
private final PrivacySettingRepository privacySettingRepository;
private final GenderRepository genderRepository;
private final PasswordEncoder passwordEncoder;
private final UserAuthServiceFacade userAuthServiceFacade;

@Override
public LoginResponse authenticateUser(LoginRequest request) {
Expand All @@ -64,42 +51,16 @@ public LoginResponse authenticateUser(LoginRequest request) {
@Override
public void signUpUser(SignUpRequest request) {
validateSignUpRequest(request);

Role userRole = roleRepository.findByCode(Roles.ROLE_USER.name())
.orElseGet(() -> roleRepository.save(new Role(Roles.ROLE_USER)));

Gender gender = genderRepository.findByCode(request.getGender().name())
.orElseThrow(() -> new IllegalArgumentException(String.format(AlertConstants.RESOURCE_NOT_FOUND, "gender", "gender.code", request.getGender())));

PrivacySetting publicSettings = privacySettingRepository.findByCode(PrivacySettings.PUBLIC.name())
.orElseGet(() -> privacySettingRepository.save(new PrivacySetting(PrivacySettings.PUBLIC)));

User user = User.builder()
.email(request.getEmail())
.name(request.getName())
.surname(request.getSurname())
.login(request.getLogin())
.birthdate(request.getBirthdate())
.gender(gender)
.profilePrivacy(publicSettings)
.postsPrivacy(publicSettings)
.friendsPrivacy(publicSettings)
.birthdate(request.getBirthdate())
.salt("salt")
.password(passwordEncoder.encode(request.getPassword()))
.role(userRole)
.build();

userRepository.save(user);
userAuthServiceFacade.createUser(request.getLogin(), request.getName(), request.getSurname(), request.getEmail(), request.getPassword(), request.getBirthdate(), Roles.ROLE_USER, request.getGender());
}

private void validateSignUpRequest(SignUpRequest request) {
boolean isLoginNotUnique = userRepository.existsByLogin(request.getLogin());
boolean isLoginNotUnique = userAuthServiceFacade.existsByLogin(request.getLogin());
if (isLoginNotUnique) {
throw new NotUniqueObjectException(String.format(AlertConstants.NOT_UNIQUE_OBJECT, "login", request.getLogin()));
}

boolean isEmailNotUnique = userRepository.existsByEmail(request.getEmail());
boolean isEmailNotUnique = userAuthServiceFacade.existsByEmail(request.getEmail());
if (isEmailNotUnique) {
throw new NotUniqueObjectException(String.format(AlertConstants.NOT_UNIQUE_OBJECT, "email", request.getEmail()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import meowhub.backend.shared.constants.AlertConstants;
import meowhub.backend.users.models.User;
import meowhub.backend.users.repositories.UserRepository;
import meowhub.backend.users.services.UserQueryService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
Expand All @@ -13,13 +12,12 @@
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepository userRepository;
private final UserQueryService userQueryService;

@Override
@Transactional
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByLogin(username)
.orElseThrow(() -> new UsernameNotFoundException(String.format(AlertConstants.USER_WITH_LOGIN_NOT_FOUND, username)));
User user = userQueryService.findUserByLogin(username);

return UserDetailsImpl.build(user);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import lombok.RequiredArgsConstructor;
import meowhub.backend.users.dtos.BasicUserInfoDto;
import meowhub.backend.users.services.UserService;
import meowhub.backend.users.services.UserQueryService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -12,10 +12,10 @@
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
private final UserQueryService userQueryService;

@GetMapping("basic-user-info")
public ResponseEntity<BasicUserInfoDto> getBasicUserInfoTemp(String login) {
return ResponseEntity.ok(userService.getBasicUserInfo(login));
return ResponseEntity.ok(userQueryService.getBasicUserInfo(login));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package meowhub.backend.users.facades;

import meowhub.backend.dtos.UserDto;

import java.util.List;

public interface UserAdminServiceFacade {
void changeUserRole(String userId, String roleName);

List<UserDto> getAllUsers();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package meowhub.backend.users.facades;

import meowhub.backend.constants.Genders;
import meowhub.backend.constants.Roles;
import meowhub.backend.users.models.User;

import java.time.LocalDate;

public interface UserAuthServiceFacade {
User createUser(String login, String name, String surname, String email, String password, LocalDate birthdate, Roles role, Genders gender);

boolean existsByLogin(String login);

boolean existsByEmail(String email);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package meowhub.backend.users.facades;

import meowhub.backend.users.dtos.BasicUserInfoDto;
import meowhub.backend.users.models.User;

public interface UserPostServiceFacade {
void validateIfUserExists(String login);

User findUserByLogin(String login);

BasicUserInfoDto getBasicUserInfo(String login);
}
Loading

0 comments on commit c12287e

Please sign in to comment.