Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.codenames.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum DefaultUserAuthRole {
GUEST("ROLE_GUEST"),
USER("ROLE_USER"),
ADMIN("ROLE_ADMIN");

private final String role;
}
3 changes: 3 additions & 0 deletions codenames-common/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@


spring:
flyway:
out-of-order: true

datasource:
url: "${MYSQL_URL:jdbc:mysql://localhost:3306/codenames}"
username: "${MYSQL_USERNAME:root}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@


CREATE TABLE IF NOT EXISTS users(
id INT NOT NULL AUTO_INCREMENT,
login VARCHAR(100) NOT NULL UNIQUE,
nickname VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);

CREATE TABLE IF NOT EXISTS users_roles(
id INT NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL,
role VARCHAR(50) NOT NULL DEFAULT "GUEST",
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES users (id)
);
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public SecurityFilterChain filterChain (HttpSecurity http) throws Exception {
.and()
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.POST , "/login", "/register").permitAll()
.requestMatchers("/whoami").permitAll()
.requestMatchers("/socket/**").permitAll()
.anyRequest().authenticated()
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.codenames.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor
@NoArgsConstructor
@Getter @Setter
public class UserAuthRoleDto {

private String role;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.codenames.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
@Table(name = "users_roles")
public class UserAuthRoleEntity {

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

@ManyToOne
@JoinColumn(name = "user_id")
private UserEntity user;

@Column(name = "role")
private String role;
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
package com.codenames.entity;


import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.List;

@Entity
@Table(name = "users")
@Getter @Setter
Expand All @@ -28,4 +32,7 @@ public class UserEntity {

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

@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<UserAuthRoleEntity> roles;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.codenames.mapper;

import com.codenames.dto.UserAuthRoleDto;
import com.codenames.entity.UserAuthRoleEntity;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface UserAuthRoleMapper {

UserAuthRoleDto userAuthRoleEntityToUserAuthRoleDto(UserAuthRoleEntity authRoleEntity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.codenames.repository;

import com.codenames.entity.UserAuthRoleEntity;
import com.codenames.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface UserAuthRoleRepository extends JpaRepository<UserAuthRoleEntity, Long> {

Optional<List<UserAuthRoleEntity>> findUserAuthRoleEntitiesByUser(UserEntity userEntity);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@
import com.codenames.dto.CredentialDto;
import com.codenames.dto.SignUpDto;
import com.codenames.entity.UserEntity;
import com.codenames.entity.UserAuthRoleEntity;
import com.codenames.exception.UserAlreadyExistsException;
import com.codenames.exception.UserNotFoundException;
import com.codenames.mapper.UserMapper;
import com.codenames.repository.UserAuthRoleRepository;
import com.codenames.exception.UserAlreadyExistsException;
import com.codenames.exception.UserNotFoundException;
import com.codenames.mapper.UserMapper;
import com.codenames.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;

import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

@Controller
Expand All @@ -26,6 +36,8 @@ public class UserService {

private final UserMapper userMapper;

private final UserAuthRoleRepository userAuthRoleRepository;

public <T> T findByNickname(Class<T> rClass, String login){
return userRepository.findByLogin(rClass, login)
.orElseThrow(() -> new UserNotFoundException("User not found", HttpStatus.NOT_FOUND));
Expand Down Expand Up @@ -69,4 +81,28 @@ public Optional<UserEntity> getUserEntityFromAuthentication(Authentication authe
return Optional.of((UserEntity) principal);

}

public Optional<UserAuthRoleEntity> getUserAuthRole(Authentication authentication){

// TODO: 22.05.2023 Perhaps this method will need to be corrected, but this is after adding a full-fledged user role assignment system

if (authentication.getAuthorities() != null){
if (!(authentication.getPrincipal() instanceof UserEntity user)){
return Optional.empty();
}

Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();

List<UserAuthRoleEntity> userAuthRoles = userAuthRoleRepository.findUserAuthRoleEntitiesByUser(user)
.orElse(new ArrayList<>());

for (UserAuthRoleEntity role : userAuthRoles){
if (authorities.contains(new SimpleGrantedAuthority(role.getRole()))) {
return Optional.of(role);
}
}
}

return Optional.empty();
}
}
16 changes: 11 additions & 5 deletions codenames-front-end/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ import {Flip, ToastContainer} from "react-toastify";
import {UserAuthRole} from "./models/CodeNames/UserAuthRole";
import {notify} from "./models";


type WhoamiResponse = {
role: UserAuthRole;
}


function App() {
const isAuthorized = useRef<boolean>(!!getAuthToken())

const [checkUserIsAuth, isLoading, error] = useFetching(async () => {
const [checkUserIsAuth] = useFetching(async () => {
try {
const response: AxiosResponse<UserAuthRole> = await authRequest("GET", RestConfig.paths.request.whoami, {})
const response: AxiosResponse<WhoamiResponse> = await authRequest("GET", RestConfig.paths.request.whoami, {})

if (response.data === UserAuthRole.USER || response.data === UserAuthRole.ADMIN) {
if (response.data.role === UserAuthRole.USER || response.data.role === UserAuthRole.ADMIN) {
isAuthorized.current = true
} else if (response.data === UserAuthRole.GUEST) {
} else if (response.data.role === UserAuthRole.GUEST) {
notify.info("You are logged in as a GUEST, which may limit your possibilities")
}
} catch (e) {
Expand Down Expand Up @@ -69,4 +75,4 @@ function App() {
);
}

export default App;
export default App;
6 changes: 3 additions & 3 deletions codenames-front-end/src/models/CodeNames/UserAuthRole.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@


export enum UserAuthRole {
GUEST = "GUEST",
USER = "USER",
ADMIN = "ADMIN"
GUEST = "ROLE_GUEST",
USER = "ROLE_USER",
ADMIN = "ROLE_ADMIN"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import com.codenames.dto.CredentialDto;
import com.codenames.dto.SignUpDto;
import com.codenames.dto.UserAuthDto;
import com.codenames.dto.UserAuthRoleDto;
import com.codenames.entity.UserAuthRoleEntity;
import com.codenames.enums.DefaultUserAuthRole;
import com.codenames.mapper.UserAuthRoleMapper;
import com.codenames.enums.UserAuthRole;
import com.codenames.mapper.UserMapper;
import com.codenames.provider.UserAuthProvider;
Expand All @@ -20,7 +24,6 @@

import java.util.Collection;


@RestController
@RequiredArgsConstructor
public class UsersController {
Expand All @@ -31,6 +34,8 @@ public class UsersController {

private final UserMapper userMapper;

private final UserAuthRoleMapper userAuthRoleMapper;

@PostMapping("/login")
public ResponseEntity<UserAuthDto> loginUser(@Valid @RequestBody CredentialDto credentialDto){
UserAuthDto user = userMapper.userEntityToUserAuthDto(userService.login(credentialDto));
Expand Down
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@
<version>8.0.33</version>
</dependency>

<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>

<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
Expand Down