mirror of
https://github.com/usatiuk/y.git
synced 2025-10-29 02:37:49 +01:00
a little cleanup
This commit is contained in:
@@ -38,6 +38,17 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: inherit;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-family: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ export function ProfileCard({
|
|||||||
actions,
|
actions,
|
||||||
alreadyFollowing,
|
alreadyFollowing,
|
||||||
isAdmin,
|
isAdmin,
|
||||||
|
isFollower,
|
||||||
}: {
|
}: {
|
||||||
username: string;
|
username: string;
|
||||||
fullName: string;
|
fullName: string;
|
||||||
@@ -16,6 +17,7 @@ export function ProfileCard({
|
|||||||
actions: boolean;
|
actions: boolean;
|
||||||
alreadyFollowing: boolean;
|
alreadyFollowing: boolean;
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
|
isFollower: boolean;
|
||||||
}) {
|
}) {
|
||||||
const homeContext = useHomeContext();
|
const homeContext = useHomeContext();
|
||||||
|
|
||||||
@@ -85,6 +87,7 @@ export function ProfileCard({
|
|||||||
</button>
|
</button>
|
||||||
</Form>
|
</Form>
|
||||||
))}
|
))}
|
||||||
|
{isFollower && <span>follows you</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ export function UserList() {
|
|||||||
return <div>Error</div>;
|
return <div>Error</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { people, following } = loaderData;
|
const { people, following, followers } = loaderData;
|
||||||
if (isError(following) || isError(people)) {
|
if (isError(following) || isError(people) || isError(followers)) {
|
||||||
return <div>Error</div>;
|
return <div>Error</div>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
@@ -32,6 +32,7 @@ export function UserList() {
|
|||||||
alreadyFollowing={following.some(
|
alreadyFollowing={following.some(
|
||||||
(f) => f.uuid == u.uuid,
|
(f) => f.uuid == u.uuid,
|
||||||
)}
|
)}
|
||||||
|
isFollower={followers.some((f) => f.uuid == u.uuid)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ export async function getFollowing(): Promise<TPersonToArrResp> {
|
|||||||
return fetchJSONAuth("/person/following", "GET", PersonToArrResp);
|
return fetchJSONAuth("/person/following", "GET", PersonToArrResp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getFollowers(): Promise<TPersonToArrResp> {
|
||||||
|
return fetchJSONAuth("/person/followers", "GET", PersonToArrResp);
|
||||||
|
}
|
||||||
|
|
||||||
export async function getPersonByUsername(
|
export async function getPersonByUsername(
|
||||||
username: string,
|
username: string,
|
||||||
): Promise<TPersonToResp> {
|
): Promise<TPersonToResp> {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export async function getPostsByAuthorUuid(
|
|||||||
author: string,
|
author: string,
|
||||||
): Promise<TPostToArrResp> {
|
): Promise<TPostToArrResp> {
|
||||||
return fetchJSONAuth(
|
return fetchJSONAuth(
|
||||||
`/post/by-author-uuid?author=${author}`,
|
`/post/by-author-uuid/${author}`,
|
||||||
"GET",
|
"GET",
|
||||||
PostToArrResp,
|
PostToArrResp,
|
||||||
);
|
);
|
||||||
@@ -45,7 +45,7 @@ export async function getPostsByAuthorUsername(
|
|||||||
author: string,
|
author: string,
|
||||||
): Promise<TPostToArrResp> {
|
): Promise<TPostToArrResp> {
|
||||||
return fetchJSONAuth(
|
return fetchJSONAuth(
|
||||||
`/post/by-author-username?author=${author}`,
|
`/post/by-author-username/${author}`,
|
||||||
"GET",
|
"GET",
|
||||||
PostToArrResp,
|
PostToArrResp,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
getAllPerson,
|
getAllPerson,
|
||||||
|
getFollowers,
|
||||||
getFollowing,
|
getFollowing,
|
||||||
getPersonByUsername,
|
getPersonByUsername,
|
||||||
getSelf,
|
getSelf,
|
||||||
@@ -36,7 +37,11 @@ export async function homeLoader() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function userListLoader() {
|
export async function userListLoader() {
|
||||||
return { people: await getAllPerson(), following: await getFollowing() };
|
return {
|
||||||
|
people: await getAllPerson(),
|
||||||
|
following: await getFollowing(),
|
||||||
|
followers: await getFollowers(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function profileLoader({
|
export async function profileLoader({
|
||||||
|
|||||||
@@ -3,22 +3,15 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
import com.usatiuk.tjv.y.server.dto.MessageCreateTo;
|
import com.usatiuk.tjv.y.server.dto.MessageCreateTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.MessageTo;
|
import com.usatiuk.tjv.y.server.dto.MessageTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.converters.MessageMapper;
|
import com.usatiuk.tjv.y.server.dto.converters.MessageMapper;
|
||||||
import com.usatiuk.tjv.y.server.entity.Message;
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
|
||||||
import com.usatiuk.tjv.y.server.security.UserRoles;
|
|
||||||
import com.usatiuk.tjv.y.server.service.ChatService;
|
import com.usatiuk.tjv.y.server.service.ChatService;
|
||||||
import com.usatiuk.tjv.y.server.service.MessageService;
|
import com.usatiuk.tjv.y.server.service.MessageService;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Collection;
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/message", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/message", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@@ -36,54 +29,29 @@ public class MessageController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-chat/{chatTd}")
|
@GetMapping(path = "/by-chat/{chatTd}")
|
||||||
public Stream<MessageTo> get(Authentication authentication, @PathVariable Long chatTd) {
|
public Collection<MessageTo> get(Authentication authentication, @PathVariable Long chatTd) {
|
||||||
var chat = chatService.readById(chatTd).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
return messageService.getByChat(authentication, chatTd);
|
||||||
var userRef = entityManager.getReference(Person.class, authentication.getName());
|
|
||||||
if (!chat.getMembers().contains(userRef))
|
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
|
||||||
|
|
||||||
return chat.getMessages().stream().map(messageMapper::makeDto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(path = "/by-chat/{chatId}")
|
@PostMapping(path = "/by-chat/{chatId}")
|
||||||
public MessageTo post(Authentication authentication, @PathVariable Long chatId, @RequestBody MessageCreateTo messageCreateTo) {
|
public MessageTo post(Authentication authentication, @PathVariable Long chatId, @RequestBody MessageCreateTo messageCreateTo) {
|
||||||
var chat = chatService.readById(chatId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
return messageService.addToChat(authentication, chatId, messageCreateTo);
|
||||||
var userRef = entityManager.getReference(Person.class, authentication.getName());
|
|
||||||
if (!chat.getMembers().contains(userRef))
|
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
|
||||||
|
|
||||||
Message message = new Message().setChat(chat).setAuthor(userRef).setContents(messageCreateTo.contents());
|
|
||||||
messageService.create(message);
|
|
||||||
return messageMapper.makeDto(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping(path = "/by-id/{id}")
|
@PatchMapping(path = "/by-id/{id}")
|
||||||
public MessageTo update(Authentication authentication, @PathVariable long id, @RequestBody MessageCreateTo messageCreateTo) {
|
public MessageTo update(Authentication authentication, @PathVariable long id, @RequestBody MessageCreateTo messageCreateTo) {
|
||||||
var message = messageService.readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
return messageService.update(authentication, id, messageCreateTo);
|
||||||
if (!Objects.equals(message.getAuthor().getUuid(), authentication.getName()))
|
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
|
||||||
message.setContents(messageCreateTo.contents());
|
|
||||||
messageService.update(message);
|
|
||||||
return messageMapper.makeDto(message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/by-id/{id}")
|
@DeleteMapping(path = "/by-id/{id}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void delete(Authentication authentication, @PathVariable long id) {
|
public void delete(Authentication authentication, @PathVariable long id) {
|
||||||
var read = messageService.readById(id);
|
messageService.delete(authentication, id);
|
||||||
if (read.isEmpty()) return;
|
|
||||||
if (!Objects.equals(read.get().getAuthor().getId(), authentication.getName())) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
|
||||||
}
|
|
||||||
messageService.deleteById(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Stream<MessageTo> getAll(Authentication authentication) {
|
public Collection<MessageTo> getAll(Authentication authentication) {
|
||||||
if (!authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
return messageService.readAll(authentication);
|
||||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
|
||||||
|
|
||||||
return StreamSupport.stream(messageService.readAll().spliterator(), false).map(messageMapper::makeDto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,6 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
import com.usatiuk.tjv.y.server.dto.PersonCreateTo;
|
import com.usatiuk.tjv.y.server.dto.PersonCreateTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.converters.PersonMapper;
|
import com.usatiuk.tjv.y.server.dto.converters.PersonMapper;
|
||||||
import com.usatiuk.tjv.y.server.entity.Chat;
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
|
||||||
import com.usatiuk.tjv.y.server.security.UserRoles;
|
|
||||||
import com.usatiuk.tjv.y.server.service.ChatService;
|
import com.usatiuk.tjv.y.server.service.ChatService;
|
||||||
import com.usatiuk.tjv.y.server.service.PersonService;
|
import com.usatiuk.tjv.y.server.service.PersonService;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
||||||
@@ -13,14 +10,10 @@ import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Collection;
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/person", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/person", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
@@ -39,103 +32,60 @@ public class PersonController {
|
|||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public PersonTo signup(@RequestBody PersonCreateTo signupRequest) throws UserAlreadyExistsException {
|
public PersonTo signup(@RequestBody PersonCreateTo signupRequest) throws UserAlreadyExistsException {
|
||||||
Person toCreate = new Person();
|
return personService.signup(signupRequest);
|
||||||
toCreate.setUsername(signupRequest.username())
|
|
||||||
.setPassword(signupRequest.password())
|
|
||||||
.setFullName(signupRequest.fullName());
|
|
||||||
|
|
||||||
Person created = personService.signup(toCreate);
|
|
||||||
|
|
||||||
return personMapper.makeDto(created);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-username/{username}")
|
@GetMapping(path = "/by-username/{username}")
|
||||||
public PersonTo getByUsername(@PathVariable String username) throws UserNotFoundException {
|
public PersonTo getByUsername(@PathVariable String username) throws UserNotFoundException {
|
||||||
Optional<Person> found = personService.readByUsername(username);
|
return personService.readByUsername(username);
|
||||||
|
|
||||||
if (found.isEmpty()) throw new UserNotFoundException();
|
|
||||||
|
|
||||||
return personMapper.makeDto(found.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-uuid/{uuid}")
|
@GetMapping(path = "/by-uuid/{uuid}")
|
||||||
public PersonTo getByUuid(@PathVariable String uuid) throws UserNotFoundException {
|
public PersonTo getByUuid(@PathVariable String uuid) throws UserNotFoundException {
|
||||||
Optional<Person> found = personService.readById(uuid);
|
return personService.readByUuid(uuid);
|
||||||
|
|
||||||
if (found.isEmpty()) throw new UserNotFoundException();
|
|
||||||
|
|
||||||
return personMapper.makeDto(found.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping(path = "/self")
|
@GetMapping(path = "/self")
|
||||||
public PersonTo getSelf(Authentication authentication) throws UserNotFoundException {
|
public PersonTo getSelf(Authentication authentication) throws UserNotFoundException {
|
||||||
Optional<Person> found = personService.readById(authentication.getName());
|
return personService.readSelf(authentication);
|
||||||
|
|
||||||
if (found.isEmpty()) throw new UserNotFoundException();
|
|
||||||
|
|
||||||
return personMapper.makeDto(found.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping(path = "/self")
|
@PatchMapping(path = "/self")
|
||||||
public PersonTo update(Authentication authentication, @RequestBody PersonCreateTo personCreateTo) {
|
public PersonTo update(Authentication authentication, @RequestBody PersonCreateTo personCreateTo) {
|
||||||
var person = personService.readById(authentication.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
return personService.update(authentication, personCreateTo);
|
||||||
person.setUsername(personCreateTo.username())
|
|
||||||
.setFullName(personCreateTo.fullName());
|
|
||||||
if (!personCreateTo.password().isEmpty()) person.setPassword(passwordEncoder.encode(personCreateTo.password()));
|
|
||||||
personService.update(person);
|
|
||||||
return personMapper.makeDto(person);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/self")
|
@DeleteMapping(path = "/self")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void delete(Authentication authentication) {
|
public void delete(Authentication authentication) {
|
||||||
var person = personService.readById(authentication.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
personService.deleteSelf(authentication);
|
||||||
for (Chat c : person.getChats()) {
|
|
||||||
c.getMembers().remove(person);
|
|
||||||
chatService.update(c);
|
|
||||||
}
|
|
||||||
personService.deleteById(authentication.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/by-uuid/{uuid}")
|
@DeleteMapping(path = "/by-uuid/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void deleteByUuid(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
public void deleteByUuid(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
||||||
if (!authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
personService.deleteByUuid(authentication, uuid);
|
||||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
|
||||||
|
|
||||||
var person = personService.readById(uuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
|
||||||
for (Chat c : person.getChats()) {
|
|
||||||
c.getMembers().remove(person);
|
|
||||||
chatService.update(c);
|
|
||||||
}
|
|
||||||
for (Person p : person.getFollowers()) {
|
|
||||||
p.getFollowing().remove(person);
|
|
||||||
personService.update(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
personService.deleteById(person.getUuid());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Stream<PersonTo> getAll() throws UserNotFoundException {
|
public Collection<PersonTo> getAll() throws UserNotFoundException {
|
||||||
return StreamSupport.stream(personService.readAll().spliterator(), false).map(personMapper::makeDto);
|
return personService.readAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/followers")
|
@GetMapping(path = "/followers")
|
||||||
public Stream<PersonTo> getFollowers(Authentication authentication) throws UserNotFoundException {
|
public Collection<PersonTo> getFollowers(Authentication authentication) throws UserNotFoundException {
|
||||||
return personService.getFollowers(authentication.getName()).stream().map(personMapper::makeDto);
|
return personService.getFollowers(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/following")
|
@GetMapping(path = "/following")
|
||||||
public Stream<PersonTo> getFollowing(Authentication authentication) throws UserNotFoundException {
|
public Collection<PersonTo> getFollowing(Authentication authentication) throws UserNotFoundException {
|
||||||
return personService.getFollowing(authentication.getName()).stream().map(personMapper::makeDto);
|
return personService.getFollowing(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/admins")
|
@GetMapping(path = "/admins")
|
||||||
public Stream<PersonTo> getAdmins() {
|
public Collection<PersonTo> getAdmins() {
|
||||||
return personService.getAdmins().stream().map(personMapper::makeDto);
|
return personService.getAdmins();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = "/admins/{uuid}")
|
@PutMapping(path = "/admins/{uuid}")
|
||||||
@@ -150,17 +100,16 @@ public class PersonController {
|
|||||||
personService.removeAdmin(authentication, uuid);
|
personService.removeAdmin(authentication, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PutMapping(path = "/following/{uuid}")
|
@PutMapping(path = "/following/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void addFollowing(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
public void addFollowing(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
||||||
personService.addFollower(authentication.getName(), uuid);
|
personService.addFollower(authentication, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/following/{uuid}")
|
@DeleteMapping(path = "/following/{uuid}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void deleteFollowing(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
public void deleteFollowing(Authentication authentication, @PathVariable String uuid) throws UserNotFoundException {
|
||||||
personService.removeFollower(authentication.getName(), uuid);
|
personService.removeFollower(authentication, uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,99 +3,63 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
import com.usatiuk.tjv.y.server.dto.PostCreateTo;
|
import com.usatiuk.tjv.y.server.dto.PostCreateTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.PostTo;
|
import com.usatiuk.tjv.y.server.dto.PostTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.converters.PostMapper;
|
import com.usatiuk.tjv.y.server.dto.converters.PostMapper;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Post;
|
|
||||||
import com.usatiuk.tjv.y.server.security.UserRoles;
|
|
||||||
import com.usatiuk.tjv.y.server.service.PostService;
|
import com.usatiuk.tjv.y.server.service.PostService;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
import java.util.stream.StreamSupport;
|
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/post", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/post", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public class PostController {
|
public class PostController {
|
||||||
private final PostService postService;
|
private final PostService postService;
|
||||||
private final PostMapper postMapper;
|
|
||||||
private final EntityManager entityManager;
|
|
||||||
|
|
||||||
public PostController(PostService postService, PostMapper postMapper, EntityManager entityManager) {
|
public PostController(PostService postService, PostMapper postMapper, EntityManager entityManager) {
|
||||||
this.postService = postService;
|
this.postService = postService;
|
||||||
this.postMapper = postMapper;
|
|
||||||
this.entityManager = entityManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public PostTo createPost(Authentication authentication, @RequestBody PostCreateTo postCreateTo) {
|
public PostTo createPost(Authentication authentication, @RequestBody PostCreateTo postCreateTo) {
|
||||||
Post post = new Post();
|
return postService.createPost(authentication, postCreateTo);
|
||||||
post.setAuthor(entityManager.getReference(Person.class, authentication.getName()));
|
|
||||||
post.setText(postCreateTo.text());
|
|
||||||
return postMapper.makeDto(postService.create(post));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-author-uuid")
|
@GetMapping(path = "/by-author-uuid/{uuid}")
|
||||||
public Stream<PostTo> readAllByAuthorUuid(@RequestParam Optional<String> author) {
|
public Collection<PostTo> readAllByAuthorUuid(@PathVariable String uuid) {
|
||||||
if (author.isPresent())
|
return postService.readByAuthorId(uuid);
|
||||||
return postService.readByAuthorId(author.get()).stream().map(postMapper::makeDto);
|
|
||||||
else
|
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-author-username")
|
@GetMapping(path = "/by-author-username/{username}")
|
||||||
public Stream<PostTo> readAllByAuthorUsername(@RequestParam Optional<String> author) {
|
public Collection<PostTo> readAllByAuthorUsername(@PathVariable String username) {
|
||||||
if (author.isPresent())
|
return postService.readByAuthorUsername(username);
|
||||||
return postService.readByAuthorUsername(author.get()).stream().map(postMapper::makeDto);
|
|
||||||
else
|
|
||||||
throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/by-following")
|
@GetMapping(path = "/by-following")
|
||||||
public Stream<PostTo> readAllByFollowees(Authentication authentication) {
|
public Collection<PostTo> readAllByFollowees(Authentication authentication) {
|
||||||
return postService.readByPersonFollowees(authentication.getName()).stream().map(postMapper::makeDto);
|
return postService.readByPersonFollowees(authentication);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/{id}")
|
@GetMapping(path = "/{id}")
|
||||||
public PostTo get(@PathVariable long id) {
|
public PostTo get(@PathVariable long id) {
|
||||||
var post = postService.readById(id);
|
return postService.readById(id);
|
||||||
if (post.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND);
|
|
||||||
return postMapper.makeDto(post.get());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping(path = "/{id}")
|
@PatchMapping(path = "/{id}")
|
||||||
public PostTo update(Authentication authentication, @PathVariable long id, @RequestBody PostCreateTo postCreateTo) {
|
public PostTo update(Authentication authentication, @PathVariable long id, @RequestBody PostCreateTo postCreateTo) {
|
||||||
var post = postService.readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
return postService.updatePost(authentication, id, postCreateTo);
|
||||||
if (!Objects.equals(post.getAuthor().getUuid(), authentication.getName()))
|
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
|
||||||
post.setText(postCreateTo.text());
|
|
||||||
postService.update(post);
|
|
||||||
return postMapper.makeDto(post);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping(path = "/{id}")
|
@DeleteMapping(path = "/{id}")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void delete(Authentication authentication, @PathVariable long id) {
|
public void delete(Authentication authentication, @PathVariable long id) {
|
||||||
var read = postService.readById(id);
|
postService.deletePost(authentication, id);
|
||||||
if (read.isEmpty()) return;
|
|
||||||
if (!Objects.equals(read.get().getAuthor().getId(), authentication.getName())) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
|
||||||
}
|
|
||||||
postService.deleteById(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public Stream<PostTo> getAll(Authentication authentication) {
|
public Collection<PostTo> getAll(Authentication authentication) {
|
||||||
if (!authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
return postService.readAll(authentication);
|
||||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
|
||||||
|
|
||||||
return StreamSupport.stream(postService.readAll().spliterator(), false).map(postMapper::makeDto);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,35 +2,28 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
|
|
||||||
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.service.LoginTokenService;
|
||||||
import com.usatiuk.tjv.y.server.service.PersonService;
|
import com.usatiuk.tjv.y.server.service.PersonService;
|
||||||
import com.usatiuk.tjv.y.server.service.TokenService;
|
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import java.util.Optional;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping(value = "/token", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/token", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public class TokenController {
|
public class TokenController {
|
||||||
private final PersonService personService;
|
private final PersonService personService;
|
||||||
private final TokenService tokenService;
|
private final LoginTokenService loginTokenService;
|
||||||
|
|
||||||
public TokenController(PersonService personService, TokenService tokenService) {
|
public TokenController(PersonService personService, LoginTokenService loginTokenService) {
|
||||||
this.personService = personService;
|
this.personService = personService;
|
||||||
this.tokenService = tokenService;
|
this.loginTokenService = loginTokenService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public TokenResponseTo request(@RequestBody TokenRequestTo tokenRequestTo) throws UserNotFoundException {
|
public TokenResponseTo request(@RequestBody TokenRequestTo tokenRequestTo) {
|
||||||
Optional<Person> found = personService.login(tokenRequestTo.username(), tokenRequestTo.password());
|
return loginTokenService.login(tokenRequestTo);
|
||||||
|
|
||||||
if (found.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Couldn't find user");
|
|
||||||
|
|
||||||
return new TokenResponseTo(tokenService.generateToken(found.get().getId()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,5 +3,8 @@ package com.usatiuk.tjv.y.server.repository;
|
|||||||
import com.usatiuk.tjv.y.server.entity.Message;
|
import com.usatiuk.tjv.y.server.entity.Message;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface MessageRepository extends CrudRepository<Message, Long> {
|
public interface MessageRepository extends CrudRepository<Message, Long> {
|
||||||
|
Collection<Message> findByChat_Id(Long chatId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.usatiuk.tjv.y.server.repository;
|
package com.usatiuk.tjv.y.server.repository;
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -9,6 +10,9 @@ import java.util.Optional;
|
|||||||
public interface PersonRepository extends CrudRepository<Person, String> {
|
public interface PersonRepository extends CrudRepository<Person, String> {
|
||||||
Optional<Person> findByUsername(String username);
|
Optional<Person> findByUsername(String username);
|
||||||
|
|
||||||
|
@Query(value = "SELECT p from Person p where p.uuid = :usernameOrId or p.username = :usernameOrId")
|
||||||
|
Optional<Person> findByUsernameOrId(String usernameOrId);
|
||||||
|
|
||||||
boolean existsByUsername(String username);
|
boolean existsByUsername(String username);
|
||||||
|
|
||||||
Collection<Person> findByAdminIsTrue();
|
Collection<Person> findByAdminIsTrue();
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.security;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class AuthenticationManagerConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager authManager(HttpSecurity http, DaoAuthenticationProvider daoAuthenticationProvider) throws Exception {
|
||||||
|
AuthenticationManagerBuilder authenticationManagerBuilder =
|
||||||
|
http.getSharedObject(AuthenticationManagerBuilder.class);
|
||||||
|
authenticationManagerBuilder.authenticationProvider(daoAuthenticationProvider);
|
||||||
|
return authenticationManagerBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.security;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class DaoAuthenticationProviderConf {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DaoAuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
|
||||||
|
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||||
|
authProvider.setUserDetailsService(userDetailsService);
|
||||||
|
authProvider.setPasswordEncoder(passwordEncoder);
|
||||||
|
return authProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.usatiuk.tjv.y.server.security;
|
package com.usatiuk.tjv.y.server.security;
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.service.TokenService;
|
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@@ -18,12 +17,12 @@ import java.util.Optional;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class JwtRequestFilter extends OncePerRequestFilter {
|
public class JwtRequestFilter extends OncePerRequestFilter {
|
||||||
private final TokenService tokenService;
|
private final JwtTokenService jwtTokenService;
|
||||||
private final JwtUserDetailsService jwtUserDetailsService;
|
private final UserDetailsService userDetailsService;
|
||||||
|
|
||||||
public JwtRequestFilter(TokenService tokenService, JwtUserDetailsService jwtUserDetailsService) {
|
public JwtRequestFilter(JwtTokenService jwtTokenService, UserDetailsService userDetailsService) {
|
||||||
this.tokenService = tokenService;
|
this.jwtTokenService = jwtTokenService;
|
||||||
this.jwtUserDetailsService = jwtUserDetailsService;
|
this.userDetailsService = userDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -36,13 +35,13 @@ public class JwtRequestFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String token = header.substring(7);
|
String token = header.substring(7);
|
||||||
Optional<String> userUuid = tokenService.parseToken(token);
|
Optional<String> userUuid = jwtTokenService.getPersonUuidFromToken(token);
|
||||||
if (userUuid.isEmpty()) {
|
if (userUuid.isEmpty()) {
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserDetails userDetails = jwtUserDetailsService.loadUserByUsername(userUuid.get());
|
UserDetails userDetails = userDetailsService.loadUserByUsername(userUuid.get());
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
||||||
userDetails, null, userDetails.getAuthorities());
|
userDetails, null, userDetails.getAuthorities());
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.security;
|
||||||
|
|
||||||
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.Claims;
|
||||||
import io.jsonwebtoken.JwtException;
|
import io.jsonwebtoken.JwtException;
|
||||||
import io.jsonwebtoken.Jwts;
|
import io.jsonwebtoken.Jwts;
|
||||||
import io.jsonwebtoken.io.Decoders;
|
|
||||||
import io.jsonwebtoken.io.Encoders;
|
|
||||||
import io.jsonwebtoken.security.Keys;
|
import io.jsonwebtoken.security.Keys;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -16,28 +14,25 @@ import java.util.Date;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class TokenServiceImpl implements TokenService {
|
public class JwtTokenService {
|
||||||
private static final Duration JWT_EXPIRY = Duration.ofMinutes(20);
|
|
||||||
|
|
||||||
private final SecretKey key;
|
private final SecretKey key;
|
||||||
|
private final Duration jwtExpiry;
|
||||||
|
|
||||||
public TokenServiceImpl(@Value("${jwt.secret}") String secret) {
|
public JwtTokenService(@Value("${jwt.secret}") String secret, @Value("${jwt.expiryMinutes}") Long expiry) {
|
||||||
// FIXME:
|
|
||||||
this.key = Keys.hmacShaKeyFor(secret.getBytes());
|
this.key = Keys.hmacShaKeyFor(secret.getBytes());
|
||||||
|
this.jwtExpiry = Duration.ofMinutes(expiry);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String generateToken(String personUuid) {
|
public String generateToken(String personUuid) {
|
||||||
Instant now = Instant.now();
|
Instant now = Instant.now();
|
||||||
return Jwts.builder()
|
return Jwts.builder()
|
||||||
.subject(personUuid)
|
.subject(personUuid)
|
||||||
.expiration(Date.from(now.plus(JWT_EXPIRY)))
|
.expiration(Date.from(now.plus(jwtExpiry)))
|
||||||
.signWith(key, Jwts.SIG.HS512)
|
.signWith(key, Jwts.SIG.HS512)
|
||||||
.compact();
|
.compact();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Optional<String> getPersonUuidFromToken(String token) {
|
||||||
public Optional<String> parseToken(String token) {
|
|
||||||
try {
|
try {
|
||||||
Claims claims = Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();
|
Claims claims = Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();
|
||||||
if (claims.getExpiration().before(new Date())) return Optional.empty();
|
if (claims.getExpiration().before(new Date())) return Optional.empty();
|
||||||
@@ -46,4 +41,5 @@ public class TokenServiceImpl implements TokenService {
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.security;
|
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.User;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class JwtUser extends User {
|
|
||||||
|
|
||||||
public JwtUser(String uuid, String hash,
|
|
||||||
Collection<? extends GrantedAuthority> authorities) {
|
|
||||||
super(uuid, hash, authorities);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.security;
|
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
|
||||||
import com.usatiuk.tjv.y.server.service.PersonService;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class JwtUserDetailsService implements UserDetailsService {
|
|
||||||
private final PersonService personService;
|
|
||||||
|
|
||||||
public JwtUserDetailsService(PersonService personService) {
|
|
||||||
this.personService = personService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UserDetails loadUserByUsername(String uuid) {
|
|
||||||
Optional<Person> person = personService.readById(uuid);
|
|
||||||
if (!person.isPresent()) throw new UsernameNotFoundException("User with UUID " + uuid + " not found");
|
|
||||||
ArrayList<SimpleGrantedAuthority> roles =
|
|
||||||
new ArrayList<>(List.of(new SimpleGrantedAuthority(UserRoles.ROLE_USER.name())));
|
|
||||||
if (person.get().isAdmin()) roles.add(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name()));
|
|
||||||
return new JwtUser(uuid, person.get().getPassword(), roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.security;
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class User extends org.springframework.security.core.userdetails.User {
|
||||||
|
|
||||||
|
public User(String uuid, String hash,
|
||||||
|
Collection<? extends GrantedAuthority> authorities) {
|
||||||
|
super(uuid, hash, authorities);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.security;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
|
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService {
|
||||||
|
private final PersonRepository personRepository;
|
||||||
|
|
||||||
|
public UserDetailsService(PersonRepository personRepository) {
|
||||||
|
this.personRepository = personRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String usernameOrUuid) {
|
||||||
|
Person person = personRepository.findByUsernameOrId(usernameOrUuid).orElseThrow(() -> new UsernameNotFoundException("Username not found"));
|
||||||
|
ArrayList<SimpleGrantedAuthority> roles =
|
||||||
|
new ArrayList<>(List.of(new SimpleGrantedAuthority(UserRoles.ROLE_USER.name())));
|
||||||
|
if (person.isAdmin()) roles.add(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name()));
|
||||||
|
return new User(person.getUuid(), person.getPassword(), roles);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ public class WebSecurityConfig {
|
|||||||
return http.cors(Customizer.withDefaults())
|
return http.cors(Customizer.withDefaults())
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.authorizeHttpRequests((authorize) -> authorize
|
.authorizeHttpRequests((authorize) -> authorize
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.GET, "/post/*")).permitAll()
|
.requestMatchers(mvc.pattern(HttpMethod.GET, "/post/**")).permitAll()
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.GET, "/post*")).permitAll()
|
.requestMatchers(mvc.pattern(HttpMethod.GET, "/post*")).permitAll()
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.POST, "/person")).permitAll()
|
.requestMatchers(mvc.pattern(HttpMethod.POST, "/person")).permitAll()
|
||||||
.requestMatchers(mvc.pattern(HttpMethod.GET, "/person")).permitAll()
|
.requestMatchers(mvc.pattern(HttpMethod.GET, "/person")).permitAll()
|
||||||
@@ -75,7 +75,6 @@ public class WebSecurityConfig {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
CorsConfigurationSource corsConfigurationSource() {
|
CorsConfigurationSource corsConfigurationSource() {
|
||||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
|||||||
@@ -3,12 +3,11 @@ package com.usatiuk.tjv.y.server.service;
|
|||||||
import com.usatiuk.tjv.y.server.dto.ChatCreateTo;
|
import com.usatiuk.tjv.y.server.dto.ChatCreateTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.ChatTo;
|
import com.usatiuk.tjv.y.server.dto.ChatTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
||||||
import com.usatiuk.tjv.y.server.entity.Chat;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface ChatService extends CrudService<Chat, Long> {
|
public interface ChatService {
|
||||||
ChatTo create(Authentication authentication, ChatCreateTo chatCreateTo);
|
ChatTo create(Authentication authentication, ChatCreateTo chatCreateTo);
|
||||||
ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo);
|
ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo);
|
||||||
|
|
||||||
@@ -18,4 +17,6 @@ public interface ChatService extends CrudService<Chat, Long> {
|
|||||||
void deleteById(Authentication authentication, Long id);
|
void deleteById(Authentication authentication, Long id);
|
||||||
|
|
||||||
Collection<PersonTo> getMembers(Authentication authentication, Long id);
|
Collection<PersonTo> getMembers(Authentication authentication, Long id);
|
||||||
|
|
||||||
|
boolean isMemberOf(String personUuid, Long chatId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import com.usatiuk.tjv.y.server.entity.Chat;
|
|||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.repository.ChatRepository;
|
import com.usatiuk.tjv.y.server.repository.ChatRepository;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -21,7 +20,7 @@ import java.util.Collection;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class ChatServiceImpl extends CrudServiceImpl<Chat, Long> implements ChatService {
|
public class ChatServiceImpl implements ChatService {
|
||||||
|
|
||||||
private final ChatRepository chatRepository;
|
private final ChatRepository chatRepository;
|
||||||
private final ChatMapper chatMapper;
|
private final ChatMapper chatMapper;
|
||||||
@@ -35,12 +34,6 @@ public class ChatServiceImpl extends CrudServiceImpl<Chat, Long> implements Chat
|
|||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected CrudRepository<Chat, Long> getRepository() {
|
|
||||||
return chatRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChatTo create(Authentication authentication, ChatCreateTo chatCreateTo) {
|
public ChatTo create(Authentication authentication, ChatCreateTo chatCreateTo) {
|
||||||
var chat = new Chat();
|
var chat = new Chat();
|
||||||
@@ -63,7 +56,7 @@ public class ChatServiceImpl extends CrudServiceImpl<Chat, Long> implements Chat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo) {
|
public ChatTo update(Authentication authentication, Long id, ChatCreateTo chatCreateTo) {
|
||||||
var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
||||||
if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName()))
|
if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName()))
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat");
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat");
|
||||||
|
|
||||||
@@ -89,7 +82,7 @@ public class ChatServiceImpl extends CrudServiceImpl<Chat, Long> implements Chat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChatTo getById(Authentication authentication, Long id) {
|
public ChatTo getById(Authentication authentication, Long id) {
|
||||||
var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
||||||
var userRef = entityManager.getReference(Person.class, authentication.getName());
|
var userRef = entityManager.getReference(Person.class, authentication.getName());
|
||||||
if (!chat.getMembers().contains(userRef))
|
if (!chat.getMembers().contains(userRef))
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
||||||
@@ -99,18 +92,25 @@ public class ChatServiceImpl extends CrudServiceImpl<Chat, Long> implements Chat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Authentication authentication, Long id) {
|
public void deleteById(Authentication authentication, Long id) {
|
||||||
var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
||||||
if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName()))
|
if (!Objects.equals(chat.getCreator().getUuid(), authentication.getName()))
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat");
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't creator of the chat");
|
||||||
deleteById(id);
|
chatRepository.delete(chat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<PersonTo> getMembers(Authentication authentication, Long id) {
|
public Collection<PersonTo> getMembers(Authentication authentication, Long id) {
|
||||||
var chat = readById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
var chat = chatRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
||||||
var userRef = entityManager.getReference(Person.class, authentication.getName());
|
var userRef = entityManager.getReference(Person.class, authentication.getName());
|
||||||
if (!chat.getMembers().contains(userRef))
|
if (!chat.getMembers().contains(userRef))
|
||||||
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
||||||
return chat.getMembers().stream().map(personMapper::makeDto).toList();
|
return chat.getMembers().stream().map(personMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMemberOf(String personUuid, Long chatId) {
|
||||||
|
var chat = chatRepository.findById(chatId).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Chat not found"));
|
||||||
|
var userRef = entityManager.getReference(Person.class, personUuid);
|
||||||
|
return chat.getMembers().contains(userRef);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.entity.EntityWithId;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface CrudService<T extends EntityWithId<ID>, ID extends Serializable> {
|
|
||||||
T create(T e);
|
|
||||||
|
|
||||||
Optional<T> readById(ID id);
|
|
||||||
|
|
||||||
Iterable<T> readAll();
|
|
||||||
|
|
||||||
void update(T e);
|
|
||||||
|
|
||||||
void deleteById(ID id);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.entity.EntityWithId;
|
|
||||||
import org.springframework.data.repository.CrudRepository;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public abstract class CrudServiceImpl<T extends EntityWithId<ID>, ID extends Serializable>
|
|
||||||
implements CrudService<T, ID> {
|
|
||||||
@Override
|
|
||||||
public T create(T e) {
|
|
||||||
if (e == null || (e.getId() != null && getRepository().existsById(e.getId())))
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
|
|
||||||
return getRepository().save(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Optional<T> readById(ID id) {
|
|
||||||
return getRepository().findById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Iterable<T> readAll() {
|
|
||||||
return getRepository().findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(T e) {
|
|
||||||
getRepository().save(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteById(ID id) {
|
|
||||||
getRepository().deleteById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract CrudRepository<T, ID> getRepository();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
||||||
|
|
||||||
|
public interface LoginTokenService {
|
||||||
|
TokenResponseTo login(TokenRequestTo tokenRequestTo);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
||||||
|
import com.usatiuk.tjv.y.server.security.JwtTokenService;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class LoginTokenServiceImpl implements LoginTokenService {
|
||||||
|
private final AuthenticationManager authenticationManager;
|
||||||
|
private final JwtTokenService jwtTokenService;
|
||||||
|
|
||||||
|
public LoginTokenServiceImpl(AuthenticationManager authenticationManager, JwtTokenService jwtTokenService) {
|
||||||
|
this.authenticationManager = authenticationManager;
|
||||||
|
this.jwtTokenService = jwtTokenService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TokenResponseTo login(TokenRequestTo tokenRequestTo) {
|
||||||
|
Authentication authentication =
|
||||||
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(tokenRequestTo.username(), tokenRequestTo.password()));
|
||||||
|
String uuid = authentication.getName();
|
||||||
|
String token = jwtTokenService.generateToken(uuid);
|
||||||
|
return new TokenResponseTo(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Message;
|
import com.usatiuk.tjv.y.server.dto.MessageCreateTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.MessageTo;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
public interface MessageService extends CrudService<Message, Long> {
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface MessageService {
|
||||||
|
Collection<MessageTo> getByChat(Authentication authentication, Long chatId);
|
||||||
|
MessageTo addToChat(Authentication authentication, Long chatId, MessageCreateTo messageCreateTo);
|
||||||
|
|
||||||
|
MessageTo update(Authentication authentication, Long id, MessageCreateTo msg);
|
||||||
|
void delete(Authentication authentication, Long id);
|
||||||
|
|
||||||
|
Collection<MessageTo> readAll(Authentication authentication);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,85 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.MessageCreateTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.MessageTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.converters.MessageMapper;
|
||||||
|
import com.usatiuk.tjv.y.server.entity.Chat;
|
||||||
import com.usatiuk.tjv.y.server.entity.Message;
|
import com.usatiuk.tjv.y.server.entity.Message;
|
||||||
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.repository.MessageRepository;
|
import com.usatiuk.tjv.y.server.repository.MessageRepository;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import com.usatiuk.tjv.y.server.security.UserRoles;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MessageServiceImpl extends CrudServiceImpl<Message, Long> implements MessageService {
|
public class MessageServiceImpl implements MessageService {
|
||||||
|
|
||||||
private final MessageRepository messageRepository;
|
private final MessageRepository messageRepository;
|
||||||
|
private final MessageMapper messageMapper;
|
||||||
|
private final ChatService chatService;
|
||||||
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
public MessageServiceImpl(MessageRepository messageRepository) {
|
public MessageServiceImpl(MessageRepository messageRepository, MessageMapper messageMapper, ChatService chatService, EntityManager entityManager) {
|
||||||
this.messageRepository = messageRepository;
|
this.messageRepository = messageRepository;
|
||||||
|
this.messageMapper = messageMapper;
|
||||||
|
this.chatService = chatService;
|
||||||
|
this.entityManager = entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CrudRepository<Message, Long> getRepository() {
|
public Collection<MessageTo> getByChat(Authentication authentication, Long chatId) {
|
||||||
return messageRepository;
|
if (!chatService.isMemberOf(authentication.getName(), chatId))
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
||||||
|
|
||||||
|
return messageRepository.findByChat_Id(chatId).stream().map(messageMapper::makeDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageTo addToChat(Authentication authentication, Long chatId, MessageCreateTo messageCreateTo) {
|
||||||
|
if (!chatService.isMemberOf(authentication.getName(), chatId))
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "User isn't member of the chat");
|
||||||
|
|
||||||
|
Message message = new Message().setChat(entityManager.getReference(Chat.class, chatId))
|
||||||
|
.setAuthor(entityManager.getReference(Person.class, authentication.getName()))
|
||||||
|
.setContents(messageCreateTo.contents());
|
||||||
|
|
||||||
|
messageRepository.save(message);
|
||||||
|
return messageMapper.makeDto(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageTo update(Authentication authentication, Long id, MessageCreateTo msg) {
|
||||||
|
var message = messageRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
|
if (!Objects.equals(message.getAuthor().getUuid(), authentication.getName()))
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
||||||
|
message.setContents(msg.contents());
|
||||||
|
messageRepository.save(message);
|
||||||
|
return messageMapper.makeDto(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Authentication authentication, Long id) {
|
||||||
|
var read = messageRepository.findById(id);
|
||||||
|
if (read.isEmpty()) return;
|
||||||
|
if (!Objects.equals(read.get().getAuthor().getId(), authentication.getName())) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
messageRepository.delete(read.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<MessageTo> readAll(Authentication authentication) {
|
||||||
|
if (!authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
||||||
|
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
|
||||||
|
return StreamSupport.stream(messageRepository.findAll().spliterator(), false).map(messageMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,37 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PersonCreateTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface PersonService extends CrudService<Person, String> {
|
public interface PersonService {
|
||||||
Person signup(Person person) throws UserAlreadyExistsException;
|
PersonTo signup(PersonCreateTo person);
|
||||||
|
|
||||||
Optional<Person> login(String username, String password);
|
Optional<Person> login(String username, String password);
|
||||||
|
|
||||||
Optional<Person> readByUsername(String username);
|
PersonTo readByUsername(String username);
|
||||||
|
PersonTo readByUuid(String uuid);
|
||||||
|
PersonTo readSelf(Authentication authentication);
|
||||||
|
|
||||||
Collection<Person> getFollowers(String uuid) throws UserNotFoundException;
|
PersonTo update(Authentication authentication, PersonCreateTo person);
|
||||||
Collection<Person> getFollowing(String uuid) throws UserNotFoundException;
|
|
||||||
|
|
||||||
void addFollower(String follower, String followee) throws UserNotFoundException;
|
void deleteSelf(Authentication authentication);
|
||||||
void removeFollower(String follower, String followee) throws UserNotFoundException;
|
void deleteByUuid(Authentication authentication, String uuid);
|
||||||
|
|
||||||
Collection<Person> getAdmins();
|
Collection<PersonTo> readAll();
|
||||||
void addAdmin(Authentication caller, String uuid) throws UserNotFoundException;
|
|
||||||
void removeAdmin(Authentication caller, String uuid) throws UserNotFoundException;
|
Collection<PersonTo> getFollowers(Authentication authentication);
|
||||||
|
Collection<PersonTo> getFollowing(Authentication authentication);
|
||||||
|
|
||||||
|
void addFollower(Authentication authentication, String followee);
|
||||||
|
void removeFollower(Authentication authentication, String followee);
|
||||||
|
|
||||||
|
Collection<PersonTo> getAdmins();
|
||||||
|
void addAdmin(Authentication caller, String uuid);
|
||||||
|
void removeAdmin(Authentication caller, String uuid);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PersonCreateTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PersonTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.converters.PersonMapper;
|
||||||
|
import com.usatiuk.tjv.y.server.entity.Chat;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
||||||
import com.usatiuk.tjv.y.server.security.UserRoles;
|
import com.usatiuk.tjv.y.server.security.UserRoles;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
import com.usatiuk.tjv.y.server.service.exceptions.UserAlreadyExistsException;
|
||||||
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
import com.usatiuk.tjv.y.server.service.exceptions.UserNotFoundException;
|
||||||
import jakarta.persistence.EntityManager;
|
import jakarta.persistence.EntityManager;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
@@ -15,36 +18,41 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class PersonServiceImpl extends CrudServiceImpl<Person, String> implements PersonService {
|
public class PersonServiceImpl implements PersonService {
|
||||||
private final PersonRepository personRepository;
|
private final PersonRepository personRepository;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
|
private final PersonMapper personMapper;
|
||||||
|
|
||||||
public PersonServiceImpl(PersonRepository personRepository,
|
public PersonServiceImpl(PersonRepository personRepository,
|
||||||
PasswordEncoder passwordEncoder, EntityManager entityManager) {
|
PasswordEncoder passwordEncoder, EntityManager entityManager, PersonMapper personMapper) {
|
||||||
this.personRepository = personRepository;
|
this.personRepository = personRepository;
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
|
this.personMapper = personMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CrudRepository<Person, String> getRepository() {
|
public PersonTo signup(PersonCreateTo signupRequest) {
|
||||||
return personRepository;
|
if (personRepository.existsByUsername(signupRequest.username()))
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Person signup(Person person) throws UserAlreadyExistsException {
|
|
||||||
if (personRepository.existsByUsername(person.getUsername()))
|
|
||||||
throw new UserAlreadyExistsException();
|
throw new UserAlreadyExistsException();
|
||||||
|
|
||||||
person.setPassword(passwordEncoder.encode(person.getPassword()));
|
Person toCreate = new Person();
|
||||||
|
|
||||||
if (personRepository.findByAdminIsTrue().isEmpty()) person.setAdmin(true);
|
toCreate.setUsername(signupRequest.username())
|
||||||
|
.setPassword(signupRequest.password())
|
||||||
|
.setFullName(signupRequest.fullName());
|
||||||
|
|
||||||
return create(person);
|
toCreate.setPassword(passwordEncoder.encode(signupRequest.password()));
|
||||||
|
|
||||||
|
if (personRepository.findByAdminIsTrue().isEmpty()) toCreate.setAdmin(true);
|
||||||
|
|
||||||
|
return personMapper.makeDto(personRepository.save(toCreate));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -57,36 +65,90 @@ public class PersonServiceImpl extends CrudServiceImpl<Person, String> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Person> readByUsername(String username) {
|
public PersonTo readByUsername(String username) {
|
||||||
return personRepository.findByUsername(username);
|
return personMapper.makeDto(personRepository.findByUsername(username).orElseThrow(UserNotFoundException::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Person> getFollowers(String uuid) throws UserNotFoundException {
|
public PersonTo readByUuid(String uuid) {
|
||||||
return personRepository.findById(uuid).orElseThrow(UserNotFoundException::new).getFollowers();
|
return personMapper.makeDto(personRepository.findById(uuid).orElseThrow(UserNotFoundException::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Person> getFollowing(String uuid) throws UserNotFoundException {
|
public PersonTo readSelf(Authentication authentication) {
|
||||||
return personRepository.findById(uuid).orElseThrow(UserNotFoundException::new).getFollowing();
|
return readByUuid(authentication.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFollower(String follower, String followee) throws UserNotFoundException {
|
public PersonTo update(Authentication authentication, PersonCreateTo person) {
|
||||||
var person = personRepository.findById(follower).orElseThrow(UserNotFoundException::new);
|
var found = personRepository.findById(authentication.getName()).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
|
found.setUsername(person.username())
|
||||||
|
.setFullName(person.fullName());
|
||||||
|
if (!person.password().isEmpty()) found.setPassword(passwordEncoder.encode(person.password()));
|
||||||
|
personRepository.save(found);
|
||||||
|
return personMapper.makeDto(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteByUuid(String uuid) {
|
||||||
|
var person = personRepository.findById(uuid).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
|
for (Chat c : person.getChats()) {
|
||||||
|
c.getMembers().remove(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Person p : person.getFollowers()) {
|
||||||
|
p.getFollowing().remove(person);
|
||||||
|
personRepository.save(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
personRepository.delete(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteSelf(Authentication authentication) {
|
||||||
|
deleteByUuid(authentication.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteByUuid(Authentication authentication, String uuid) {
|
||||||
|
if ((!Objects.equals(authentication.getName(), uuid)) &&
|
||||||
|
!authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
||||||
|
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
deleteByUuid(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PersonTo> readAll() {
|
||||||
|
return StreamSupport.stream(personRepository.findAll().spliterator(), false).map(personMapper::makeDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PersonTo> getFollowers(Authentication authentication) {
|
||||||
|
return personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new)
|
||||||
|
.getFollowers().stream().map(personMapper::makeDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PersonTo> getFollowing(Authentication authentication) {
|
||||||
|
return personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new)
|
||||||
|
.getFollowing().stream().map(personMapper::makeDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addFollower(Authentication authentication, String followee) {
|
||||||
|
var person = personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new);
|
||||||
person.getFollowing().add(entityManager.getReference(Person.class, followee));
|
person.getFollowing().add(entityManager.getReference(Person.class, followee));
|
||||||
personRepository.save(person);
|
personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeFollower(String follower, String followee) throws UserNotFoundException {
|
public void removeFollower(Authentication authentication, String followee) {
|
||||||
var person = personRepository.findById(follower).orElseThrow(UserNotFoundException::new);
|
var person = personRepository.findById(authentication.getName()).orElseThrow(UserNotFoundException::new);
|
||||||
person.getFollowing().remove(entityManager.getReference(Person.class, followee));
|
person.getFollowing().remove(entityManager.getReference(Person.class, followee));
|
||||||
personRepository.save(person);
|
personRepository.save(person);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAdmin(Authentication caller, String uuid) throws UserNotFoundException {
|
public void addAdmin(Authentication caller, String uuid) {
|
||||||
if (!caller.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
if (!caller.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
||||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
|
||||||
@@ -96,7 +158,7 @@ public class PersonServiceImpl extends CrudServiceImpl<Person, String> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeAdmin(Authentication caller, String uuid) throws UserNotFoundException {
|
public void removeAdmin(Authentication caller, String uuid) {
|
||||||
if (!caller.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
if (!caller.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
||||||
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
|
||||||
@@ -109,7 +171,7 @@ public class PersonServiceImpl extends CrudServiceImpl<Person, String> implement
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Person> getAdmins() {
|
public Collection<PersonTo> getAdmins() {
|
||||||
return personRepository.findByAdminIsTrue();
|
return personRepository.findByAdminIsTrue().stream().map(personMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
import com.usatiuk.tjv.y.server.entity.Post;
|
import com.usatiuk.tjv.y.server.dto.PostCreateTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PostTo;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public interface PostService extends CrudService<Post, Long> {
|
public interface PostService {
|
||||||
Collection<Post> readByAuthorId(String authorUuid);
|
PostTo createPost(Authentication authentication, PostCreateTo postCreateTo);
|
||||||
|
PostTo updatePost(Authentication authentication, Long id, PostCreateTo postCreateTo);
|
||||||
|
void deletePost(Authentication authentication, Long id);
|
||||||
|
|
||||||
Collection<Post> readByAuthorUsername(String authorUsername);
|
PostTo readById(Long id);
|
||||||
|
|
||||||
Collection<Post> readByPersonFollowees(String personUuid);
|
Collection<PostTo> readByAuthorId(String authorUuid);
|
||||||
|
Collection<PostTo> readByAuthorUsername(String authorUsername);
|
||||||
|
|
||||||
|
Collection<PostTo> readByPersonFollowees(Authentication authentication);
|
||||||
|
|
||||||
|
Collection<PostTo> readAll(Authentication authentication);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,89 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
package com.usatiuk.tjv.y.server.service;
|
||||||
|
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PostCreateTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.PostTo;
|
||||||
|
import com.usatiuk.tjv.y.server.dto.converters.PostMapper;
|
||||||
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.entity.Post;
|
import com.usatiuk.tjv.y.server.entity.Post;
|
||||||
import com.usatiuk.tjv.y.server.repository.PostRepository;
|
import com.usatiuk.tjv.y.server.repository.PostRepository;
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import com.usatiuk.tjv.y.server.security.UserRoles;
|
||||||
|
import jakarta.persistence.EntityManager;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class PostServiceImpl extends CrudServiceImpl<Post, Long> implements PostService {
|
public class PostServiceImpl implements PostService {
|
||||||
private final PostRepository postRepository;
|
private final PostRepository postRepository;
|
||||||
|
private final PostMapper postMapper;
|
||||||
|
private final EntityManager entityManager;
|
||||||
|
|
||||||
public PostServiceImpl(PostRepository postRepository) {
|
public PostServiceImpl(PostRepository postRepository, PostMapper postMapper, EntityManager entityManager) {
|
||||||
this.postRepository = postRepository;
|
this.postRepository = postRepository;
|
||||||
|
this.postMapper = postMapper;
|
||||||
|
this.entityManager = entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected CrudRepository<Post, Long> getRepository() {
|
public PostTo createPost(Authentication authentication, PostCreateTo postCreateTo) {
|
||||||
return postRepository;
|
Post post = new Post();
|
||||||
|
post.setAuthor(entityManager.getReference(Person.class, authentication.getName()));
|
||||||
|
post.setText(postCreateTo.text());
|
||||||
|
return postMapper.makeDto(postRepository.save(post));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Post> readByAuthorId(String authorId) {
|
public PostTo readById(Long id) {
|
||||||
return postRepository.findByAuthorUuid(authorId);
|
return postMapper.makeDto(postRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Post not found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Post> readByAuthorUsername(String authorUsername) {
|
public Collection<PostTo> readByAuthorId(String authorId) {
|
||||||
return postRepository.findByAuthorUsername(authorUsername);
|
return postRepository.findByAuthorUuid(authorId).stream().map(postMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Post> readByPersonFollowees(String personUuid) {
|
public Collection<PostTo> readByAuthorUsername(String authorUsername) {
|
||||||
return postRepository.findByPersonFollowees(personUuid);
|
return postRepository.findByAuthorUsername(authorUsername).stream().map(postMapper::makeDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PostTo> readByPersonFollowees(Authentication authentication) {
|
||||||
|
return postRepository.findByPersonFollowees(authentication.getName()).stream().map(postMapper::makeDto).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PostTo updatePost(Authentication authentication, Long id, PostCreateTo postCreateTo) {
|
||||||
|
var post = postRepository.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
|
||||||
|
if (!Objects.equals(post.getAuthor().getUuid(), authentication.getName()))
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
||||||
|
post.setText(postCreateTo.text());
|
||||||
|
postRepository.save(post);
|
||||||
|
return postMapper.makeDto(post);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deletePost(Authentication authentication, Long id) {
|
||||||
|
var read = postRepository.findById(id);
|
||||||
|
if (read.isEmpty()) return;
|
||||||
|
if (!Objects.equals(read.get().getAuthor().getId(), authentication.getName())) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.FORBIDDEN);
|
||||||
|
}
|
||||||
|
postRepository.delete(read.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<PostTo> readAll(Authentication authentication) {
|
||||||
|
if (!authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoles.ROLE_ADMIN.name())))
|
||||||
|
throw new ResponseStatusException(HttpStatus.UNAUTHORIZED);
|
||||||
|
|
||||||
|
return StreamSupport.stream(postRepository.findAll().spliterator(), false).map(postMapper::makeDto).toList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.usatiuk.tjv.y.server.service;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public interface TokenService {
|
|
||||||
String generateToken(String personUuid);
|
|
||||||
|
|
||||||
Optional<String> parseToken(String token);
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
@ResponseStatus(HttpStatus.CONFLICT)
|
@ResponseStatus(HttpStatus.CONFLICT)
|
||||||
public class UserAlreadyExistsException extends Exception {
|
public class UserAlreadyExistsException extends RuntimeException {
|
||||||
public UserAlreadyExistsException() {
|
public UserAlreadyExistsException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
@ResponseStatus(HttpStatus.NOT_FOUND)
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
public class UserNotFoundException extends Exception {
|
public class UserNotFoundException extends RuntimeException {
|
||||||
public UserNotFoundException() {
|
public UserNotFoundException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserNotFoundException(String message) {
|
public UserNotFoundException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
jwt.secret=JKLASJKLASJKLJHKLDFAHJKFDSHJKFJHKDSHJKFHJKSDFJHKSDJHKFJHKS98346783467899782345jkhgsdoigh938g
|
jwt.secret=JKLASJKLASJKLJHKLDFAHJKFDSHJKFJHKDSHJKFHJKSDFJHKSDJHKFJHKS98346783467899782345jkhgsdoigh938g
|
||||||
|
jwt.expiryMinutes=20
|
||||||
logging.level.root=DEBUG
|
logging.level.root=DEBUG
|
||||||
logging.level.org.springframework.security=DEBUG
|
logging.level.org.springframework.security=DEBUG
|
||||||
spring.datasource.url=jdbc:h2:file:~/tjvserver.h2
|
spring.datasource.url=jdbc:h2:file:~/tjvserver.h2
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class ChatControllerTest extends DemoDataDbTest {
|
|||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldNotChatUnauthorized() {
|
void shouldNotGetChatUnauthorized() {
|
||||||
var response = restTemplate.exchange(addr + "/chat/by-id/" + chat1.getId(), HttpMethod.GET,
|
var response = restTemplate.exchange(addr + "/chat/by-id/" + chat1.getId(), HttpMethod.GET,
|
||||||
new HttpEntity<>(createAuthHeaders(person3Auth)),
|
new HttpEntity<>(createAuthHeaders(person3Auth)),
|
||||||
ErrorTo.class);
|
ErrorTo.class);
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
|
|
||||||
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
||||||
import com.usatiuk.tjv.y.server.entity.Chat;
|
import com.usatiuk.tjv.y.server.entity.Chat;
|
||||||
|
import com.usatiuk.tjv.y.server.entity.Message;
|
||||||
import com.usatiuk.tjv.y.server.entity.Person;
|
import com.usatiuk.tjv.y.server.entity.Person;
|
||||||
import com.usatiuk.tjv.y.server.entity.Post;
|
import com.usatiuk.tjv.y.server.entity.Post;
|
||||||
import com.usatiuk.tjv.y.server.repository.ChatRepository;
|
import com.usatiuk.tjv.y.server.repository.ChatRepository;
|
||||||
|
import com.usatiuk.tjv.y.server.repository.MessageRepository;
|
||||||
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
import com.usatiuk.tjv.y.server.repository.PersonRepository;
|
||||||
import com.usatiuk.tjv.y.server.repository.PostRepository;
|
import com.usatiuk.tjv.y.server.repository.PostRepository;
|
||||||
import com.usatiuk.tjv.y.server.service.TokenService;
|
import com.usatiuk.tjv.y.server.security.JwtTokenService;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -35,13 +37,15 @@ public abstract class DemoDataDbTest {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
@Autowired
|
@Autowired
|
||||||
private TokenService tokenService;
|
private JwtTokenService jwtTokenService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private PersonRepository personRepository;
|
private PersonRepository personRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private PostRepository postRepository;
|
private PostRepository postRepository;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ChatRepository chatRepository;
|
private ChatRepository chatRepository;
|
||||||
|
@Autowired
|
||||||
|
private MessageRepository messageRepository;
|
||||||
|
|
||||||
protected static final String person1Password = "p1p";
|
protected static final String person1Password = "p1p";
|
||||||
protected Person person1;
|
protected Person person1;
|
||||||
@@ -59,6 +63,11 @@ public abstract class DemoDataDbTest {
|
|||||||
protected Chat chat1;
|
protected Chat chat1;
|
||||||
protected Chat chat2;
|
protected Chat chat2;
|
||||||
|
|
||||||
|
protected Message message1;
|
||||||
|
protected Message message2;
|
||||||
|
protected Message message3;
|
||||||
|
protected Message message4;
|
||||||
|
|
||||||
protected HttpHeaders createAuthHeaders(TokenResponseTo personAuth) {
|
protected HttpHeaders createAuthHeaders(TokenResponseTo personAuth) {
|
||||||
HttpHeaders headers = new HttpHeaders();
|
HttpHeaders headers = new HttpHeaders();
|
||||||
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
|
||||||
@@ -74,20 +83,20 @@ public abstract class DemoDataDbTest {
|
|||||||
.setUsername("person1")
|
.setUsername("person1")
|
||||||
.setFullName("Person 1")
|
.setFullName("Person 1")
|
||||||
.setPassword(passwordEncoder.encode(person1Password)));
|
.setPassword(passwordEncoder.encode(person1Password)));
|
||||||
person1Auth = new TokenResponseTo(tokenService.generateToken(person1.getUuid()));
|
person1Auth = new TokenResponseTo(jwtTokenService.generateToken(person1.getUuid()));
|
||||||
person2 = personRepository.save(
|
person2 = personRepository.save(
|
||||||
new Person()
|
new Person()
|
||||||
.setUsername("person2")
|
.setUsername("person2")
|
||||||
.setFullName("Person 2")
|
.setFullName("Person 2")
|
||||||
.setPassword(passwordEncoder.encode(person2Password)).setFollowing(List.of(person1)));
|
.setPassword(passwordEncoder.encode(person2Password)).setFollowing(List.of(person1)));
|
||||||
person2Auth = new TokenResponseTo(tokenService.generateToken(person2.getUuid()));
|
person2Auth = new TokenResponseTo(jwtTokenService.generateToken(person2.getUuid()));
|
||||||
person3 = personRepository.save(
|
person3 = personRepository.save(
|
||||||
new Person()
|
new Person()
|
||||||
.setUsername("person3")
|
.setUsername("person3")
|
||||||
.setFullName("Person 3")
|
.setFullName("Person 3")
|
||||||
.setPassword(passwordEncoder.encode(person3Password))
|
.setPassword(passwordEncoder.encode(person3Password))
|
||||||
.setFollowing(List.of(person2, person1)));
|
.setFollowing(List.of(person2, person1)));
|
||||||
person3Auth = new TokenResponseTo(tokenService.generateToken(person3.getUuid()));
|
person3Auth = new TokenResponseTo(jwtTokenService.generateToken(person3.getUuid()));
|
||||||
|
|
||||||
post1 = postRepository.save(new Post().setAuthor(person1).setText("post 1"));
|
post1 = postRepository.save(new Post().setAuthor(person1).setText("post 1"));
|
||||||
post2 = postRepository.save(new Post().setAuthor(person2).setText("post 2"));
|
post2 = postRepository.save(new Post().setAuthor(person2).setText("post 2"));
|
||||||
@@ -102,12 +111,17 @@ public abstract class DemoDataDbTest {
|
|||||||
.setCreator(person3)
|
.setCreator(person3)
|
||||||
.setMembers(List.of(person2, person3))
|
.setMembers(List.of(person2, person3))
|
||||||
.setName("Chat 1"));
|
.setName("Chat 1"));
|
||||||
|
|
||||||
|
message1 = messageRepository.save(new Message().setAuthor(person1).setChat(chat1).setContents("message 1"));
|
||||||
|
message2 = messageRepository.save(new Message().setAuthor(person2).setChat(chat1).setContents("message2"));
|
||||||
|
message3 = messageRepository.save(new Message().setAuthor(person2).setChat(chat2).setContents("message 3"));
|
||||||
|
message4 = messageRepository.save(new Message().setAuthor(person3).setChat(chat2).setContents("message 4"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void erase() {
|
void erase() {
|
||||||
assert !TestTransaction.isActive();
|
assert !TestTransaction.isActive();
|
||||||
JdbcTestUtils.deleteFromTables(jdbcTemplate, "person_follows", "chat_person", "post", "chat", "message", "person");
|
JdbcTestUtils.deleteFromTables(jdbcTemplate, "person_follows", "chat_person", "post", "message", "chat", "person");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class PostControllerTest extends DemoDataDbTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldGetByAuthor() {
|
void shouldGetByAuthor() {
|
||||||
var response = restTemplate.exchange(addr + "/post/by-author-uuid?author=" + person1.getUuid(), HttpMethod.GET,
|
var response = restTemplate.exchange(addr + "/post/by-author-uuid/" + person1.getUuid(), HttpMethod.GET,
|
||||||
HttpEntity.EMPTY, PostTo[].class);
|
HttpEntity.EMPTY, PostTo[].class);
|
||||||
|
|
||||||
Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
|
Assertions.assertEquals(HttpStatus.OK, response.getStatusCode());
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package com.usatiuk.tjv.y.server.controller;
|
|||||||
|
|
||||||
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
import com.usatiuk.tjv.y.server.dto.TokenRequestTo;
|
||||||
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
import com.usatiuk.tjv.y.server.dto.TokenResponseTo;
|
||||||
import com.usatiuk.tjv.y.server.service.TokenService;
|
import com.usatiuk.tjv.y.server.security.JwtTokenService;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -13,7 +13,7 @@ import org.springframework.http.HttpStatus;
|
|||||||
public class TokenControllerTest extends DemoDataDbTest {
|
public class TokenControllerTest extends DemoDataDbTest {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TokenService tokenService;
|
private JwtTokenService jwtTokenService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldLogin() {
|
void shouldLogin() {
|
||||||
@@ -26,7 +26,7 @@ public class TokenControllerTest extends DemoDataDbTest {
|
|||||||
TokenResponseTo parsedResponse = response.getBody();
|
TokenResponseTo parsedResponse = response.getBody();
|
||||||
Assertions.assertNotNull(parsedResponse);
|
Assertions.assertNotNull(parsedResponse);
|
||||||
|
|
||||||
Assertions.assertTrue(tokenService.parseToken(parsedResponse.token()).isPresent());
|
Assertions.assertTrue(jwtTokenService.getPersonUuidFromToken(parsedResponse.token()).isPresent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
jwt.secret=FLJKDSDKLJFJKLISDAHJKFHOUIJOHUIJFHUOI$UIHGOUIOFG$#UIOYFOUYIG#$UIOHDUGHIOHUGIHJFHJLKDFHJLKDHJLKFSJDHKFHJKLSH
|
jwt.secret=FLJKDSDKLJFJKLISDAHJKFHOUIJOHUIJFHUOI$UIHGOUIOFG$#UIOYFOUYIG#$UIOHDUGHIOHUGIHJFHJLKDFHJLKDHJLKFSJDHKFHJKLSH
|
||||||
|
jwt.expiryMinutes=20
|
||||||
logging.level.root=DEBUG
|
logging.level.root=DEBUG
|
||||||
logging.level.org.springframework.security=DEBUG
|
logging.level.org.springframework.security=DEBUG
|
||||||
Reference in New Issue
Block a user