Промежуточный коммит
This commit is contained in:
parent
3b2bd8cf85
commit
3df60c757f
@ -1,5 +1,5 @@
|
|||||||
import './App.css';
|
import './App.css';
|
||||||
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
|
import { useRoutes, Outlet, BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||||
import Header from './components/common/Header';
|
import Header from './components/common/Header';
|
||||||
import MainPage from './components/pages/MainPage';
|
import MainPage from './components/pages/MainPage';
|
||||||
import Footer from './components/common/Footer';
|
import Footer from './components/common/Footer';
|
||||||
@ -10,42 +10,38 @@ import { useState } from 'react';
|
|||||||
import AuthorsPage from './components/pages/dev/AuthorsPage';
|
import AuthorsPage from './components/pages/dev/AuthorsPage';
|
||||||
import GenresPage from './components/pages/dev/GenresPage';
|
import GenresPage from './components/pages/dev/GenresPage';
|
||||||
import ForumPage from './components/pages/ForumPage'
|
import ForumPage from './components/pages/ForumPage'
|
||||||
function Router(props) {
|
import SignUpPage from './components/pages/SignUpPage';
|
||||||
return useRoutes(props.rootRoute);
|
import PrivateRoutes from './utils/PrivateRoutes';
|
||||||
}
|
|
||||||
|
|
||||||
export default function AppDev() {
|
export default function AppDev() {
|
||||||
const[searchValue, setSearchValue] = useState();
|
const[searchValue, setSearchValue] = useState();
|
||||||
const routes = [
|
const routes = [
|
||||||
{ index: true, element: <MainPage />},
|
{ path: '/', label: "Главная" },
|
||||||
{ path: '', element: <MainPage/>, label: 'Главная' },
|
{ path: '/Books', label: "Книги" },
|
||||||
{ path: 'Books', element: <BooksPage searchValue={searchValue} setSearchValue={setSearchValue}/>, label: 'Книги' },
|
{ path: '/Authors', label: "Авторы" },
|
||||||
{ path: 'Authors', element: <AuthorsPage/>, label: 'Авторы' },
|
{ path: '/Genres', label: "Жанры" },
|
||||||
{ path: 'Genres', element: <GenresPage/>, label: 'Жанры' },
|
{ path: '/Forum', label: 'Форум'}
|
||||||
{ path: 'Forum', element:<ForumPage/>, label: 'Форум'},
|
|
||||||
{ path: 'Login', element: <LoginPage/>},
|
|
||||||
{ path: 'Contacts', element: <Contacts/>}
|
|
||||||
];
|
];
|
||||||
const links = routes.filter(route => route.hasOwnProperty('label'));
|
|
||||||
const rootRoute = [
|
|
||||||
{ path: '/', element: render(links), children: routes }
|
|
||||||
];
|
|
||||||
|
|
||||||
function render(links) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Header links={links} single={routes[routes.length-2]} setSearchValue={setSearchValue} />
|
|
||||||
<div className="container-fluid">
|
|
||||||
<Outlet />
|
|
||||||
</div>
|
|
||||||
<Footer link={routes[routes.length-1]}/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<Router rootRoute={ rootRoute } />
|
<Header links={routes} setSearchValue={setSearchValue} />
|
||||||
</BrowserRouter>
|
<div>
|
||||||
|
<Routes>
|
||||||
|
<Route element={<PrivateRoutes/>}>
|
||||||
|
<Route element={<MainPage/>} path="/" exact />
|
||||||
|
<Route element={<MainPage />} path="*" />
|
||||||
|
<Route element={<BooksPage searchValue={searchValue} setSearchValue={setSearchValue}/>} path="/Books"/>
|
||||||
|
<Route element={<AuthorsPage/>} path="/Authors"/>
|
||||||
|
<Route element={<GenresPage/>} path="/Genres"/>
|
||||||
|
<Route element={<ForumPage/>} path="/Forum"/>
|
||||||
|
<Route element={<Contacts/>} path="/Contacts"/>
|
||||||
|
</Route>
|
||||||
|
<Route element={<LoginPage/>} path="/Login"/>
|
||||||
|
<Route element={<SignUpPage/>} path="/Signup"/>
|
||||||
|
</Routes>
|
||||||
|
</div>
|
||||||
|
<Footer link={{path: '/Contacts'}}/>
|
||||||
|
</BrowserRouter>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ import ForumPage from './components/pages/ForumPage';
|
|||||||
import Contacts from './components/pages/Contacts';
|
import Contacts from './components/pages/Contacts';
|
||||||
import LoginPage from './components/pages/LoginPage';
|
import LoginPage from './components/pages/LoginPage';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
import SignUpPage from './components/pages/SignUpPage';
|
||||||
function Router(props) {
|
function Router(props) {
|
||||||
return useRoutes(props.rootRoute);
|
return useRoutes(props.rootRoute);
|
||||||
}
|
}
|
||||||
@ -21,6 +22,7 @@ function Router(props) {
|
|||||||
{ path: 'authors', element: null, label: 'Авторы' },
|
{ path: 'authors', element: null, label: 'Авторы' },
|
||||||
{ path: 'forum', element: <ForumPage/>, label: 'Форум' },
|
{ path: 'forum', element: <ForumPage/>, label: 'Форум' },
|
||||||
{ path: 'login', element: <LoginPage/>},
|
{ path: 'login', element: <LoginPage/>},
|
||||||
|
{ path: 'signup', element: <SignUpPage/>},
|
||||||
{ path: 'contacts', element: <Contacts/>}
|
{ path: 'contacts', element: <Contacts/>}
|
||||||
];
|
];
|
||||||
const links = routes.filter(route => route.hasOwnProperty('label'));
|
const links = routes.filter(route => route.hasOwnProperty('label'));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { NavLink } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
export default function Footer(props) {
|
export default function Footer(props) {
|
||||||
return (
|
return (
|
||||||
<footer className="mt-auto" style={{ backgroundColor: "rgb(235,185,185)" }}>
|
<footer className="mt-auto" style={{ backgroundColor: "rgb(235,185,185)" }}>
|
||||||
@ -6,9 +6,9 @@ export default function Footer(props) {
|
|||||||
<div className="col-lg-3 col-md-6 mb-4 mb-md-0">
|
<div className="col-lg-3 col-md-6 mb-4 mb-md-0">
|
||||||
<ul className="list-unstyled mb-0">
|
<ul className="list-unstyled mb-0">
|
||||||
<li>
|
<li>
|
||||||
<NavLink className="nav-link" to={props.link.path}>
|
<Link className="nav-link" to={props.link.path}>
|
||||||
Контакты
|
Контакты
|
||||||
</NavLink>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a className="nav-link" href="#">
|
<a className="nav-link" href="#">
|
||||||
|
@ -1,13 +1,21 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { NavLink } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import AuthService from "../../services/AuthService";
|
||||||
|
|
||||||
export default function Header(props) {
|
export default function Header(props) {
|
||||||
|
const navigate = useNavigate();
|
||||||
const[state, setState] = useState({
|
const[state, setState] = useState({
|
||||||
text:""
|
text:""
|
||||||
});
|
});
|
||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
setState({ ...state, [event.target.id]: event.target.value });
|
setState({ ...state, [event.target.id]: event.target.value });
|
||||||
};
|
};
|
||||||
|
const handleLogout = () =>{
|
||||||
|
AuthService.logout();
|
||||||
|
navigate("/Login");
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
const handleSubmit = (event) => {
|
const handleSubmit = (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
props.setSearchValue(state.text)
|
props.setSearchValue(state.text)
|
||||||
@ -42,9 +50,9 @@ export default function Header(props) {
|
|||||||
<ul className="nav nav-tabs justify-content-center border-bottom-0">
|
<ul className="nav nav-tabs justify-content-center border-bottom-0">
|
||||||
{props.links.map((route) => (
|
{props.links.map((route) => (
|
||||||
<li key={route.path} className="nav-item">
|
<li key={route.path} className="nav-item">
|
||||||
<NavLink className="nav-link" to={route.path}>
|
<Link className="nav-link" to={route.path}>
|
||||||
{route.label}
|
{route.label}
|
||||||
</NavLink>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@ -63,9 +71,9 @@ export default function Header(props) {
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<span className="col text-end">
|
<span className="col text-end">
|
||||||
<NavLink className="nav-link" to={props.single.path}>
|
<Link className="nav-link" onClick={handleLogout} to={""}>
|
||||||
Вход/Регистрация
|
Выход
|
||||||
</NavLink>
|
</Link>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
import AuthService from "../../services/AuthService"
|
||||||
export default function LoginPage(props) {
|
export default function LoginPage(props) {
|
||||||
const formRef = React.createRef();
|
const formRef = React.createRef();
|
||||||
const [error, setError] = useState(false)
|
const navigate = useNavigate();
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
login: "",
|
login: "",
|
||||||
password: ""
|
password: ""
|
||||||
@ -10,37 +13,33 @@ export default function LoginPage(props) {
|
|||||||
const handleChange = (event) => {
|
const handleChange = (event) => {
|
||||||
setState({ ...state, [event.target.name]: event.target.value});
|
setState({ ...state, [event.target.name]: event.target.value});
|
||||||
};
|
};
|
||||||
const validateEmail = (email) => {
|
|
||||||
return String(email)
|
|
||||||
.toLowerCase()
|
|
||||||
.match(
|
|
||||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
|
||||||
);
|
|
||||||
};
|
|
||||||
const handleSubmit = (event) =>{
|
const handleSubmit = (event) =>{
|
||||||
if (!validateEmail(state.login) || state.password.length <=0) {
|
event.preventDefault();
|
||||||
event.preventDefault();
|
setMessage("");
|
||||||
setError(true)
|
AuthService.login(state.login, state.password).then(
|
||||||
event.stopPropagation();
|
() => {
|
||||||
}
|
navigate("/");
|
||||||
else{
|
window.location.reload();
|
||||||
setError(false)
|
},
|
||||||
}
|
(error) => {
|
||||||
}
|
const resMessage =
|
||||||
|
(error.response &&
|
||||||
|
error.response.data &&
|
||||||
|
error.response.data.message) ||
|
||||||
|
error.message ||
|
||||||
|
error.toString();
|
||||||
|
|
||||||
|
setMessage(resMessage);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="flex-shrink-0" style={{backgroundColor : 'rgb(255,255,255)'}}>
|
<div className="flex-shrink-0" style={{backgroundColor : 'rgb(255,255,255)'}}>
|
||||||
<div className="d-flex justify-content-center">
|
<div className="d-flex justify-content-center">
|
||||||
<form ref={formRef} noValidate className="w-50 ms-2 needs-validation" onSubmit={(e)=>handleSubmit(e)}>
|
<form ref={formRef} className="w-50 ms-2" onSubmit={(e)=>handleSubmit(e)}>
|
||||||
<h2 className="py-3">Вход</h2>
|
<h2 className="py-3">Вход</h2>
|
||||||
<h4>Логин</h4>
|
<h4>Логин</h4>
|
||||||
<input className="form-control my-2" name="login" value={state.login} onChange={(e)=>handleChange(e)} type="email" required />
|
<input className="form-control my-2" name="login" value={state.login} onChange={(e)=>handleChange(e)} type="text" required />
|
||||||
{
|
|
||||||
error && !validateEmail(state.login)
|
|
||||||
?<div>
|
|
||||||
Пожалуйста введите электронную почту вида: "*****@**.**"
|
|
||||||
</div>
|
|
||||||
:<div></div>
|
|
||||||
}
|
|
||||||
<h4>Пароль</h4>
|
<h4>Пароль</h4>
|
||||||
<input
|
<input
|
||||||
className="form-control my-2"
|
className="form-control my-2"
|
||||||
@ -50,22 +49,22 @@ export default function LoginPage(props) {
|
|||||||
onChange={(e)=>handleChange(e)}
|
onChange={(e)=>handleChange(e)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
{
|
|
||||||
error && state.password.length <=0
|
|
||||||
?<div>
|
|
||||||
Пожалуйста введите пароль
|
|
||||||
</div>
|
|
||||||
:<div></div>
|
|
||||||
}
|
|
||||||
<div>
|
<div>
|
||||||
<button className="btn btn-primary m-2" type="submit">
|
<button className="btn btn-primary m-2" type="submit">
|
||||||
Войти
|
Войти
|
||||||
</button>
|
</button>
|
||||||
<a href="" style={{marginTop: 1, marginLeft: 1}}>
|
<a href="/Signup" style={{marginTop: 1, marginLeft: 1}}>
|
||||||
Зарегистрируйтесь, если нет аккаунта, здесь
|
Зарегистрируйтесь, если нет аккаунта, здесь
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
{message && (
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
{message}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
82
front/src/components/pages/SignUpPage.jsx
Normal file
82
front/src/components/pages/SignUpPage.jsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import AuthService from "../../services/AuthService"
|
||||||
|
export default function SignUpPage(props) {
|
||||||
|
const formRef = React.createRef();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [message, setMessage] = useState("");
|
||||||
|
const [state, setState] = useState({
|
||||||
|
login: "",
|
||||||
|
password: "",
|
||||||
|
passwordConfirm: ""
|
||||||
|
});
|
||||||
|
const handleChange = (event) => {
|
||||||
|
setState({ ...state, [event.target.name]: event.target.value});
|
||||||
|
};
|
||||||
|
const handleSubmit = (event) =>{
|
||||||
|
event.preventDefault();
|
||||||
|
setMessage("");
|
||||||
|
AuthService.register(state.login, state.password, state.passwordConfirm).then(
|
||||||
|
() => {
|
||||||
|
navigate("/Login");
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
const resMessage =
|
||||||
|
(error.response &&
|
||||||
|
error.response.data &&
|
||||||
|
error.response.data.message) ||
|
||||||
|
error.message ||
|
||||||
|
error.toString();
|
||||||
|
|
||||||
|
setMessage(resMessage);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="flex-shrink-0" style={{backgroundColor : 'rgb(255,255,255)'}}>
|
||||||
|
<div className="d-flex justify-content-center">
|
||||||
|
<form ref={formRef} className="w-50 ms-2" onSubmit={(e)=>handleSubmit(e)}>
|
||||||
|
<h2 className="py-3">Вход</h2>
|
||||||
|
<h4>Логин</h4>
|
||||||
|
<input className="form-control my-2" name="login" value={state.login} onChange={(e)=>handleChange(e)} type="text" required />
|
||||||
|
<h4>Пароль</h4>
|
||||||
|
<input
|
||||||
|
className="form-control my-2"
|
||||||
|
type="password"
|
||||||
|
name="password"
|
||||||
|
value={state.password}
|
||||||
|
onChange={(e)=>handleChange(e)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<h4>Подтверждение пароля</h4>
|
||||||
|
<input
|
||||||
|
className="form-control my-2"
|
||||||
|
type="password"
|
||||||
|
name="passwordConfirm"
|
||||||
|
value={state.passwordConfirm}
|
||||||
|
onChange={(e)=>handleChange(e)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-primary m-2" type="submit">
|
||||||
|
Создать аккаунт
|
||||||
|
</button>
|
||||||
|
<Link className="nav-link" to={"/Login"}>
|
||||||
|
Назад
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{message && (
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="alert alert-danger" role="alert">
|
||||||
|
{message}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
6
front/src/modelsDTO/UserLoginDto.js
Normal file
6
front/src/modelsDTO/UserLoginDto.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default class UserLoginDto {
|
||||||
|
constructor(data) {
|
||||||
|
this.login = data?.login;
|
||||||
|
this.password = data?.password;
|
||||||
|
}
|
||||||
|
}
|
7
front/src/modelsDTO/UserSignUpDto.js
Normal file
7
front/src/modelsDTO/UserSignUpDto.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default class UserSignUpDto {
|
||||||
|
constructor(data) {
|
||||||
|
this.login = data?.login;
|
||||||
|
this.password = data?.password;
|
||||||
|
this.passwordConfirm = data?.passwordConfirm;
|
||||||
|
}
|
||||||
|
}
|
32
front/src/services/AuthService.js
Normal file
32
front/src/services/AuthService.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import UserSignUpDto from "../modelsDTO/UserSignUpDto";
|
||||||
|
import UserLoginDto from "../modelsDTO/UserLoginDto";
|
||||||
|
|
||||||
|
const API_URL = "http://localhost:8080";
|
||||||
|
|
||||||
|
const register = (username, password, passwordConfirm) => {
|
||||||
|
return axios.post(API_URL + "/signup", new UserSignUpDto({login: username,
|
||||||
|
password: password,
|
||||||
|
passwordConfirm: passwordConfirm}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const login = (username, password) => {
|
||||||
|
return axios
|
||||||
|
.post(API_URL + "/jwt/login", new UserLoginDto({login: username, password: password}))
|
||||||
|
.then((response) => {
|
||||||
|
if(response.status === 200){
|
||||||
|
localStorage.setItem("token", response.data)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
localStorage.removeItem("token");
|
||||||
|
};
|
||||||
|
const AuthService = {
|
||||||
|
register,
|
||||||
|
login,
|
||||||
|
logout,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AuthService;
|
14
front/src/utils/PrivateRoutes.jsx
Normal file
14
front/src/utils/PrivateRoutes.jsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Outlet, Navigate } from 'react-router-dom'
|
||||||
|
|
||||||
|
const PrivateRoutes = () => {
|
||||||
|
let getPermission = false;
|
||||||
|
let userToken = localStorage.getItem("token");
|
||||||
|
if(userToken){
|
||||||
|
getPermission = true;
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
getPermission ? <Outlet/> : <Navigate to="/Login"/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PrivateRoutes
|
@ -1,6 +1,7 @@
|
|||||||
package com.labwork01.app.author.model;
|
package com.labwork01.app.author.model;
|
||||||
|
|
||||||
import com.labwork01.app.book.model.Book;
|
import com.labwork01.app.book.model.Book;
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -19,6 +20,9 @@ public class Author {
|
|||||||
private String patronymic;
|
private String patronymic;
|
||||||
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "author", fetch = FetchType.EAGER)
|
@OneToMany(cascade = CascadeType.REMOVE, mappedBy = "author", fetch = FetchType.EAGER)
|
||||||
private List<Book> books =new ArrayList<>();
|
private List<Book> books =new ArrayList<>();
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name= "user_id", nullable = false)
|
||||||
|
private User user;
|
||||||
|
|
||||||
public List<Book> getBooks() {
|
public List<Book> getBooks() {
|
||||||
return books;
|
return books;
|
||||||
@ -71,6 +75,12 @@ public class Author {
|
|||||||
public void setPatronymic(String patronymic) {
|
public void setPatronymic(String patronymic) {
|
||||||
this.patronymic = patronymic;
|
this.patronymic = patronymic;
|
||||||
}
|
}
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
@ -88,6 +98,7 @@ public class Author {
|
|||||||
"id=" + id +
|
"id=" + id +
|
||||||
", name='" + name + '\'' + '}' +
|
", name='" + name + '\'' + '}' +
|
||||||
", surname='" + surname + '\'' + '}' +
|
", surname='" + surname + '\'' + '}' +
|
||||||
", patronymic='" + patronymic + '\'' + '}';
|
", patronymic='" + patronymic + '\'' +
|
||||||
|
", user='" + user.toString() + '\'' + '}' +'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,12 @@ package com.labwork01.app.author.service;
|
|||||||
|
|
||||||
import com.labwork01.app.author.model.Author;
|
import com.labwork01.app.author.model.Author;
|
||||||
import com.labwork01.app.author.repository.AuthorRepository;
|
import com.labwork01.app.author.repository.AuthorRepository;
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
|
import com.labwork01.app.user.model.UserRole;
|
||||||
|
import com.labwork01.app.user.service.UserService;
|
||||||
import com.labwork01.app.util.validation.ValidatorUtil;
|
import com.labwork01.app.util.validation.ValidatorUtil;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -12,15 +17,25 @@ import java.util.Optional;
|
|||||||
@Service
|
@Service
|
||||||
public class AuthorService {
|
public class AuthorService {
|
||||||
private final AuthorRepository authorRepository;
|
private final AuthorRepository authorRepository;
|
||||||
|
private final UserService userService;
|
||||||
private final ValidatorUtil validatorUtil;
|
private final ValidatorUtil validatorUtil;
|
||||||
public AuthorService(AuthorRepository authorRepository, ValidatorUtil validatorUtil){
|
public AuthorService(AuthorRepository authorRepository, UserService userService, ValidatorUtil validatorUtil){
|
||||||
this.authorRepository = authorRepository;
|
this.authorRepository = authorRepository;
|
||||||
|
this.userService = userService;
|
||||||
this.validatorUtil = validatorUtil;
|
this.validatorUtil = validatorUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Author addAuthor(String name, String surname, String patronymic) {
|
public Author addAuthor(String name, String surname, String patronymic) {
|
||||||
final Author author = new Author(name,surname,patronymic);
|
final Author author = new Author(name,surname,patronymic);
|
||||||
|
Object currentUser = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
if(currentUser instanceof UserDetails){
|
||||||
|
String username = ((UserDetails)currentUser).getUsername();
|
||||||
|
User user = userService.findByLogin(username);
|
||||||
|
if(user.getRole() == UserRole.ADMIN){
|
||||||
|
author.setUser(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
validatorUtil.validate(author);
|
validatorUtil.validate(author);
|
||||||
return authorRepository.save(author);
|
return authorRepository.save(author);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.labwork01.app.book.model;
|
|||||||
|
|
||||||
import com.labwork01.app.author.model.Author;
|
import com.labwork01.app.author.model.Author;
|
||||||
import com.labwork01.app.genre.model.Genre;
|
import com.labwork01.app.genre.model.Genre;
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -25,6 +26,9 @@ public class Book {
|
|||||||
@ManyToOne(fetch = FetchType.EAGER)
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
@JoinColumn(name = "author_id", nullable = false)
|
@JoinColumn(name = "author_id", nullable = false)
|
||||||
private Author author;
|
private Author author;
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name= "user_id", nullable = false)
|
||||||
|
private User user;
|
||||||
public Book() {
|
public Book() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +93,12 @@ public class Book {
|
|||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
@ -111,6 +121,7 @@ public class Book {
|
|||||||
", description='" + description + '\'' +
|
", description='" + description + '\'' +
|
||||||
", author='" + author.toString() + '\'' +
|
", author='" + author.toString() + '\'' +
|
||||||
", genres='" + String.join(", ",getGenresName()) + '\'' +
|
", genres='" + String.join(", ",getGenresName()) + '\'' +
|
||||||
|
", user='" + user.toString() + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,12 @@ import com.labwork01.app.book.model.Book;
|
|||||||
import com.labwork01.app.book.repository.BookRepository;
|
import com.labwork01.app.book.repository.BookRepository;
|
||||||
import com.labwork01.app.genre.model.Genre;
|
import com.labwork01.app.genre.model.Genre;
|
||||||
import com.labwork01.app.genre.service.GenreService;
|
import com.labwork01.app.genre.service.GenreService;
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
|
import com.labwork01.app.user.model.UserRole;
|
||||||
|
import com.labwork01.app.user.service.UserService;
|
||||||
import com.labwork01.app.util.validation.ValidatorUtil;
|
import com.labwork01.app.util.validation.ValidatorUtil;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -18,11 +23,13 @@ public class BookService {
|
|||||||
private final BookRepository bookRepository;
|
private final BookRepository bookRepository;
|
||||||
private final GenreService genreService;
|
private final GenreService genreService;
|
||||||
private final AuthorService authorService;
|
private final AuthorService authorService;
|
||||||
|
private final UserService userService;
|
||||||
private final ValidatorUtil validatorUtil;
|
private final ValidatorUtil validatorUtil;
|
||||||
public BookService(BookRepository bookRepository,GenreService genreService, AuthorService authorService, ValidatorUtil validatorUtil){
|
public BookService(BookRepository bookRepository,GenreService genreService, AuthorService authorService, UserService userService, ValidatorUtil validatorUtil){
|
||||||
this.bookRepository = bookRepository;
|
this.bookRepository = bookRepository;
|
||||||
this.genreService = genreService;
|
this.genreService = genreService;
|
||||||
this.authorService = authorService;
|
this.authorService = authorService;
|
||||||
|
this.userService = userService;
|
||||||
this.validatorUtil = validatorUtil;
|
this.validatorUtil = validatorUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +40,14 @@ public class BookService {
|
|||||||
for (Genre genre: genres) {
|
for (Genre genre: genres) {
|
||||||
book.addGenre(genre);
|
book.addGenre(genre);
|
||||||
}
|
}
|
||||||
|
Object currentUser = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
if(currentUser instanceof UserDetails){
|
||||||
|
String username = ((UserDetails)currentUser).getUsername();
|
||||||
|
User user = userService.findByLogin(username);
|
||||||
|
if(user.getRole() == UserRole.ADMIN){
|
||||||
|
book.setUser(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
validatorUtil.validate(book);
|
validatorUtil.validate(book);
|
||||||
return bookRepository.save(book);
|
return bookRepository.save(book);
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,17 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
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.WebSecurityCustomizer;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@EnableGlobalMethodSecurity(securedEnabled = true)
|
||||||
public class SecurityConfiguration {
|
public class SecurityConfiguration {
|
||||||
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
|
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
|
||||||
|
|
||||||
@ -48,6 +52,7 @@ public class SecurityConfiguration {
|
|||||||
.authorizeHttpRequests()
|
.authorizeHttpRequests()
|
||||||
.requestMatchers("/", SPA_URL_MASK).permitAll()
|
.requestMatchers("/", SPA_URL_MASK).permitAll()
|
||||||
.requestMatchers(HttpMethod.POST, UserController.URL_LOGIN).permitAll()
|
.requestMatchers(HttpMethod.POST, UserController.URL_LOGIN).permitAll()
|
||||||
|
.requestMatchers(HttpMethod.POST, UserController.URL_SIGNUP).permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
.and()
|
.and()
|
||||||
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
|
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
|
||||||
@ -65,7 +70,12 @@ public class SecurityConfiguration {
|
|||||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||||
return (web) -> web.ignoring()
|
return (web) -> web.ignoring()
|
||||||
.requestMatchers(HttpMethod.OPTIONS, "/**")
|
.requestMatchers(HttpMethod.OPTIONS, "/**")
|
||||||
.requestMatchers("/**/*.{js,html,css,png}")
|
.requestMatchers("/*.js")
|
||||||
|
.requestMatchers("/*.html")
|
||||||
|
.requestMatchers("/*.css")
|
||||||
|
.requestMatchers("/assets/**")
|
||||||
|
.requestMatchers("/favicon.ico")
|
||||||
|
.requestMatchers("/.js", "/.css")
|
||||||
.requestMatchers("/swagger-ui/index.html")
|
.requestMatchers("/swagger-ui/index.html")
|
||||||
.requestMatchers("/webjars/**")
|
.requestMatchers("/webjars/**")
|
||||||
.requestMatchers("/swagger-resources/**")
|
.requestMatchers("/swagger-resources/**")
|
||||||
|
@ -6,10 +6,7 @@ import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerF
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.servlet.config.annotation.*;
|
||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistration;
|
|
||||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
class WebConfiguration implements WebMvcConfigurer {
|
class WebConfiguration implements WebMvcConfigurer {
|
||||||
@ -21,7 +18,7 @@ class WebConfiguration implements WebMvcConfigurer {
|
|||||||
public void addViewControllers(ViewControllerRegistry registry) {
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
registry.addViewController(SecurityConfiguration.SPA_URL_MASK).setViewName("forward:/");
|
registry.addViewController(SecurityConfiguration.SPA_URL_MASK).setViewName("forward:/");
|
||||||
ViewControllerRegistration registration = registry.addViewController("/notFound");
|
ViewControllerRegistration registration = registry.addViewController("/notFound");
|
||||||
registration.setViewName("forward:/index.html");
|
registration.setViewName("forward:/");
|
||||||
registration.setStatusCode(HttpStatus.OK);
|
registration.setStatusCode(HttpStatus.OK);
|
||||||
|
|
||||||
// Alternative way (404 error hits the console):
|
// Alternative way (404 error hits the console):
|
||||||
@ -34,4 +31,16 @@ class WebConfiguration implements WebMvcConfigurer {
|
|||||||
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
|
container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(
|
||||||
|
ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/static/**")
|
||||||
|
.addResourceLocations("/WEB-INF/view/react/build/static/");
|
||||||
|
registry.addResourceHandler("/*.js")
|
||||||
|
.addResourceLocations("/WEB-INF/view/react/build/");
|
||||||
|
registry.addResourceHandler("/*.json")
|
||||||
|
.addResourceLocations("/WEB-INF/view/react/build/");
|
||||||
|
registry.addResourceHandler("/*.ico")
|
||||||
|
.addResourceLocations("/WEB-INF/view/react/build/");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.labwork01.app.genre.model;
|
package com.labwork01.app.genre.model;
|
||||||
|
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -11,6 +12,9 @@ public class Genre {
|
|||||||
private Long id;
|
private Long id;
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String name;
|
private String name;
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name= "user_id", nullable = false)
|
||||||
|
private User user;
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -23,6 +27,12 @@ public class Genre {
|
|||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
public Genre() {
|
public Genre() {
|
||||||
}
|
}
|
||||||
public Genre(String name) {
|
public Genre(String name) {
|
||||||
@ -44,6 +54,7 @@ public class Genre {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "Genre{" +
|
return "Genre{" +
|
||||||
"id=" + id +
|
"id=" + id +
|
||||||
", name='" + name + '\'' + '}';
|
", name='" + name + '\'' +
|
||||||
|
", user='" + user.toString() + '\'' +'}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,12 @@ package com.labwork01.app.genre.service;
|
|||||||
import com.labwork01.app.book.model.Book;
|
import com.labwork01.app.book.model.Book;
|
||||||
import com.labwork01.app.genre.model.Genre;
|
import com.labwork01.app.genre.model.Genre;
|
||||||
import com.labwork01.app.genre.repository.GenreRepository;
|
import com.labwork01.app.genre.repository.GenreRepository;
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
|
import com.labwork01.app.user.model.UserRole;
|
||||||
|
import com.labwork01.app.user.service.UserService;
|
||||||
import com.labwork01.app.util.validation.ValidatorUtil;
|
import com.labwork01.app.util.validation.ValidatorUtil;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -13,15 +18,25 @@ import java.util.Optional;
|
|||||||
@Service
|
@Service
|
||||||
public class GenreService {
|
public class GenreService {
|
||||||
private final GenreRepository genreRepository;
|
private final GenreRepository genreRepository;
|
||||||
|
private final UserService userService;
|
||||||
private final ValidatorUtil validatorUtil;
|
private final ValidatorUtil validatorUtil;
|
||||||
public GenreService(GenreRepository genreRepository, ValidatorUtil validatorUtil){
|
public GenreService(GenreRepository genreRepository, UserService userService, ValidatorUtil validatorUtil){
|
||||||
this.genreRepository = genreRepository;
|
this.genreRepository = genreRepository;
|
||||||
|
this.userService = userService;
|
||||||
this.validatorUtil = validatorUtil;
|
this.validatorUtil = validatorUtil;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Genre addGenre(String name) {
|
public Genre addGenre(String name) {
|
||||||
final Genre genre = new Genre(name);
|
final Genre genre = new Genre(name);
|
||||||
|
Object currentUser = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
||||||
|
if(currentUser instanceof UserDetails){
|
||||||
|
String username = ((UserDetails)currentUser).getUsername();
|
||||||
|
User user = userService.findByLogin(username);
|
||||||
|
if(user.getRole() == UserRole.ADMIN){
|
||||||
|
genre.setUser(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
validatorUtil.validate(genre);
|
validatorUtil.validate(genre);
|
||||||
return genreRepository.save(genre);
|
return genreRepository.save(genre);
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,45 @@
|
|||||||
package com.labwork01.app.user.controller;
|
package com.labwork01.app.user.controller;
|
||||||
|
|
||||||
|
import com.labwork01.app.configuration.OpenAPI30Configuration;
|
||||||
|
import com.labwork01.app.user.model.User;
|
||||||
|
import com.labwork01.app.user.model.UserRole;
|
||||||
import com.labwork01.app.user.service.UserService;
|
import com.labwork01.app.user.service.UserService;
|
||||||
|
import com.labwork01.app.util.validation.ValidationException;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class UserController {
|
public class UserController {
|
||||||
public static final String URL_LOGIN = "/jwt/login";
|
public static final String URL_LOGIN = "/jwt/login";
|
||||||
|
public static final String URL_SIGNUP = "/signup";
|
||||||
|
public static final String URL_MAIN = "/users";
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
public UserController(UserService userService) {
|
public UserController(UserService userService) {
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
@GetMapping(OpenAPI30Configuration.API_PREFIX + URL_MAIN)
|
||||||
|
@Secured({UserRole.AsString.ADMIN})
|
||||||
|
public Page<UserDto> getUsers(@RequestParam(defaultValue = "1") int page,
|
||||||
|
@RequestParam(defaultValue = "5") int size){
|
||||||
|
return userService.findAllPages(page, size).map(UserDto::new);
|
||||||
|
}
|
||||||
@PostMapping(URL_LOGIN)
|
@PostMapping(URL_LOGIN)
|
||||||
public String login(@RequestBody @Valid UserDto userDto) {
|
public String login(@RequestBody @Valid UserLoginDto userLoginDto) {
|
||||||
return userService.loginAndGetToken(userDto);
|
return userService.loginAndGetToken(userLoginDto);
|
||||||
|
}
|
||||||
|
@PostMapping(URL_SIGNUP)
|
||||||
|
public String signup(@RequestBody @Valid UserSignupDto userSignupDto){
|
||||||
|
try {
|
||||||
|
User user = userService.createUser(userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
||||||
|
return user.getLogin() + "was created";
|
||||||
|
}
|
||||||
|
catch(ValidationException e){
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,11 @@ import com.labwork01.app.user.model.UserRole;
|
|||||||
public class UserDto {
|
public class UserDto {
|
||||||
private final long id;
|
private final long id;
|
||||||
private final String login;
|
private final String login;
|
||||||
private final String password;
|
|
||||||
private final UserRole role;
|
private final UserRole role;
|
||||||
|
|
||||||
public UserDto(User user) {
|
public UserDto(User user) {
|
||||||
this.id = user.getId();
|
this.id = user.getId();
|
||||||
this.login = user.getLogin();
|
this.login = user.getLogin();
|
||||||
this.password = user.getPassword();
|
|
||||||
this.role = user.getRole();
|
this.role = user.getRole();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +25,4 @@ public class UserDto {
|
|||||||
public UserRole getRole() {
|
public UserRole getRole() {
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
public String getPassword(){
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.labwork01.app.user.controller;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
public class UserLoginDto {
|
||||||
|
@NotBlank
|
||||||
|
private String login;
|
||||||
|
@NotBlank
|
||||||
|
private String password;
|
||||||
|
public String getLogin() {
|
||||||
|
return login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogin(String login) {
|
||||||
|
this.login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ package com.labwork01.app.user.service;
|
|||||||
|
|
||||||
import com.labwork01.app.configuration.jwt.JwtException;
|
import com.labwork01.app.configuration.jwt.JwtException;
|
||||||
import com.labwork01.app.configuration.jwt.JwtProvider;
|
import com.labwork01.app.configuration.jwt.JwtProvider;
|
||||||
import com.labwork01.app.user.controller.UserDto;
|
import com.labwork01.app.user.controller.UserLoginDto;
|
||||||
import com.labwork01.app.user.model.User;
|
import com.labwork01.app.user.model.User;
|
||||||
import com.labwork01.app.user.model.UserRole;
|
import com.labwork01.app.user.model.UserRole;
|
||||||
import com.labwork01.app.user.repository.UserRepository;
|
import com.labwork01.app.user.repository.UserRepository;
|
||||||
@ -61,7 +61,7 @@ public class UserService implements UserDetailsService {
|
|||||||
return userRepository.save(user);
|
return userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String loginAndGetToken(UserDto userDto) {
|
public String loginAndGetToken(UserLoginDto userDto) {
|
||||||
final User user = findByLogin(userDto.getLogin());
|
final User user = findByLogin(userDto.getLogin());
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
throw new UserNotFoundException(userDto.getLogin());
|
throw new UserNotFoundException(userDto.getLogin());
|
||||||
|
Loading…
Reference in New Issue
Block a user