Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cu 8696y76jy epic api v3 kinga traczyk #92

Merged
merged 3 commits into from
Dec 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading