A self hosted chat application with end-to-end encrypted messaging.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

150 lines
6.2 KiB

package org.ros.chatto.controller;
import java.security.Principal;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.validation.Valid;
import org.ros.chatto.dto.ActiveUserDTO;
import org.ros.chatto.dto.ChatMessageDTO;
import org.ros.chatto.dto.MessageCipherDTO;
import org.ros.chatto.error.ErrorModel;
import org.ros.chatto.error.ErrorResponse;
import org.ros.chatto.service.ChatService;
import org.ros.chatto.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/chat")
public class ChatMessageController {
@Autowired
private ChatService chatService;
@Autowired
private UserService userService;
@PostMapping(value = "/post/message", consumes = { "application/json" })
@ResponseBody
public ResponseEntity<?> newMessage(@RequestBody @Valid ChatMessageDTO chatMessageDTO, BindingResult bindingResult,
Principal principal) {
if (bindingResult.hasErrors()) {
// return new ResponseEntity<List<FieldError>>(bindingResult.getFieldErrors(),HttpStatus.BAD_REQUEST);
return new ResponseEntity<ErrorResponse>(handleException(bindingResult), HttpStatus.BAD_REQUEST);
}
MessageCipherDTO messageCipher = chatMessageDTO.getMessageCipher();
String fromUser = principal.getName();
String toUser = chatMessageDTO.getToUser();
System.out.println("Message cipher = " + messageCipher);
chatMessageDTO = chatService.saveNewMessage(fromUser, toUser, messageCipher);
return new ResponseEntity<ChatMessageDTO>(chatMessageDTO, HttpStatus.CREATED);
}
/**
* Method that check against {@code @Valid} Objects passed to controller
* endpoints
*
* @param exception
* @return a {@code ErrorResponse}
* @see com.aroussi.util.validation.ErrorResponse
*/
// @ExceptionHandler(value = MethodArgumentNotValidException.class)
// @ResponseStatus(HttpStatus.BAD_REQUEST)
// public ErrorResponse handleException(MethodArgumentNotValidException exception) {
//
// List<ErrorModel> errorMessages = exception.getBindingResult().getFieldErrors().stream()
// .map(err -> new ErrorModel(err.getField(), err.getRejectedValue(), err.getDefaultMessage())).distinct()
// .collect(Collectors.toList());
// return ErrorResponse.builder().errorMessage(errorMessages).build();
// }
//
// @ExceptionHandler(value = MethodArgumentNotValidException.class)
// @ResponseStatus(HttpStatus.BAD_REQUEST)
public ErrorResponse handleException(BindingResult bindingResult) {
List<ErrorModel> errorMessages = bindingResult.getFieldErrors().stream()
.map(err -> new ErrorModel(err.getField(), err.getRejectedValue(), err.getDefaultMessage())).distinct()
.collect(Collectors.toList());
return ErrorResponse.builder().errorMessage(errorMessages).build();
}
@GetMapping(value = "/get/messages/{userName}")
@ResponseBody
public List<ChatMessageDTO> sendAllMessages(@PathVariable String userName, Principal principal) {
List<ChatMessageDTO> chatMessageDTOs = chatService.getAllMessages(principal.getName(), userName);
return chatMessageDTOs;
}
@GetMapping(value = "/get/messages/{userName}", params = { "page", "size" })
@ResponseBody
public List<ChatMessageDTO> findPaginated(@RequestParam("page") int page, @RequestParam("size") int size,
@PathVariable String userName, Principal principal) {
List<ChatMessageDTO> chatMessageDTOs = chatService.getMessagePage(principal.getName(), userName, page, size);
return chatMessageDTOs;
}
@GetMapping(value = "/get/messages/{userName}/{lastMessageTime}")
@ResponseBody
public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName, @PathVariable String lastMessageTime,
Principal principal) {
System.out.println("Last message time = " + lastMessageTime);
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
// date/time
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
// offset (hh:mm - "+00:00" when it's zero)
.optionalStart().appendOffset("+HH:MM", "+00:00").optionalEnd()
// offset (hhmm - "+0000" when it's zero)
.optionalStart().appendOffset("+HHMM", "+0000").optionalEnd()
// offset (hh - "Z" when it's zero)
.optionalStart().appendOffset("+HH", "Z").optionalEnd()
// create formatter
.toFormatter();
Date date = Date.from(OffsetDateTime.parse(lastMessageTime, formatter).toInstant());
List<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages(principal.getName(), userName, date);
return chatMessageDTOs;
}
@GetMapping("/get/users")
public List<String> getAllOtherUsers(Principal principal) {
return userService.findAllOtherUsers(principal.getName());
}
@GetMapping("/get/active-users")
public List<ActiveUserDTO> getAllOtherActiveUsers(Principal principal) {
return userService.getOtherActiveUsers(principal.getName());
}
@GetMapping("/get/token")
public ResponseEntity<?> getToken() {
return new ResponseEntity<String>(HttpStatus.OK);
}
}
//public ResponseEntity<List<ChatMessage>> getMessages(@PathVariable String userName, Principal principal) {
////List<ChatMessage> chatMessages = chatMessageRepository.getAllMessages(principal.getName(), userName);
//
//// return posts.stream()
//// .map(post -> convertToDto(post))
//// .collect(Collectors.toList());
//return new ResponseEntity<List<ChatMessage>>(chatMessages, HttpStatus.OK);
//}