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