Architecture improvements and validation
Improved system architecture and added sample regex validation to registration
This commit is contained in:
parent
4607ae5e17
commit
acbacc8fa8
@ -100,18 +100,20 @@
|
|||||||
<artifactId>cache-api</artifactId>
|
<artifactId>cache-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId>
|
||||||
|
<version>2.2.11</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId>
|
||||||
|
<artifactId>jaxb-core</artifactId> <version>2.2.11</version> </dependency> -->
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
|
||||||
|
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.sun.xml.bind</groupId>
|
<groupId>javax.xml.bind</groupId>
|
||||||
<artifactId>jaxb-impl</artifactId>
|
<artifactId>jaxb-api</artifactId>
|
||||||
<version>2.2.11</version>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jaxb</groupId>
|
||||||
|
<artifactId>jaxb-runtime</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.sun.xml.bind</groupId>
|
|
||||||
<artifactId>jaxb-core</artifactId>
|
|
||||||
<version>2.2.11</version>
|
|
||||||
</dependency>
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity5 -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.thymeleaf.extras</groupId>
|
<groupId>org.thymeleaf.extras</groupId>
|
||||||
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
|
||||||
@ -124,6 +126,7 @@
|
|||||||
<!-- <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId>
|
<!-- <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId>
|
||||||
<version>1.1.0</version> </dependency> -->
|
<version>1.1.0</version> </dependency> -->
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -31,7 +31,7 @@ public final class RESTAuthenticationEntryPoint
|
|||||||
response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName());
|
response.addHeader("WWW-Authenticate", "Basic realm=" +getRealmName());
|
||||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
PrintWriter writer = response.getWriter();
|
PrintWriter writer = response.getWriter();
|
||||||
writer.println("HTTP Status 401 - " + authEx.getMessage());
|
writer.println("HTTP ApplicationStatus 401 - " + authEx.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,14 +1,25 @@
|
|||||||
package org.ros.chatto.controller;
|
package org.ros.chatto.controller;
|
||||||
|
|
||||||
|
import java.security.Principal;
|
||||||
|
|
||||||
|
import org.ros.chatto.service.UserService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/admin")
|
@RequestMapping("/admin")
|
||||||
public class AdminController {
|
public class AdminController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
@RequestMapping
|
@RequestMapping
|
||||||
public String viewManageUsers() {
|
public ModelAndView viewManageUsers(Principal principal) {
|
||||||
return "/admin/home";
|
ModelAndView modelAndView = new ModelAndView("/admin/home");
|
||||||
|
modelAndView.addObject("user", new String());
|
||||||
|
modelAndView.addObject("userNames", userService.getAllRegularUsers());
|
||||||
|
return modelAndView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,87 @@
|
|||||||
|
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 org.ros.chatto.dto.ChatMessageDTO;
|
||||||
|
import org.ros.chatto.dto.ReencryptionDTO;
|
||||||
|
import org.ros.chatto.model.ChatMessage;
|
||||||
|
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.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.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/admin")
|
||||||
|
public class AdminRESTController {
|
||||||
|
@Autowired
|
||||||
|
private ChatService chatService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@PostMapping(value = "/post/re-encrypt", consumes = { "application/json" })
|
||||||
|
@ResponseBody
|
||||||
|
public ResponseEntity<ReencryptionDTO> reencryptMessages(@RequestBody List<ReencryptionDTO> reencryptionDTOs,
|
||||||
|
Principal principal) {
|
||||||
|
if (reencryptionDTOs.size() > 0) {
|
||||||
|
chatService.reencryptMessages(reencryptionDTOs);
|
||||||
|
}
|
||||||
|
return new ResponseEntity<ReencryptionDTO>(HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = "/get/messages/{userName}")
|
||||||
|
@ResponseBody
|
||||||
|
public List<ReencryptionDTO> sendAllMessages(@PathVariable String userName, Principal principal) {
|
||||||
|
List<ReencryptionDTO> reencryptionDTOs = chatService.getAllMessagesForReencryption(principal.getName(), userName);
|
||||||
|
return reencryptionDTOs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//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);
|
||||||
|
//}
|
@ -8,6 +8,8 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.ros.chatto.dto.ChatMessageDTO;
|
import org.ros.chatto.dto.ChatMessageDTO;
|
||||||
|
import org.ros.chatto.dto.MessageCipherDTO;
|
||||||
|
import org.ros.chatto.dto.ReencryptionDTO;
|
||||||
import org.ros.chatto.model.MessageCipher;
|
import org.ros.chatto.model.MessageCipher;
|
||||||
import org.ros.chatto.service.ChatService;
|
import org.ros.chatto.service.ChatService;
|
||||||
import org.ros.chatto.service.UserService;
|
import org.ros.chatto.service.UserService;
|
||||||
@ -19,6 +21,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
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.ResponseBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -34,7 +37,7 @@ public class ChatMessageController {
|
|||||||
@PostMapping(value = "/post/message", consumes = { "application/json" })
|
@PostMapping(value = "/post/message", consumes = { "application/json" })
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ResponseEntity<ChatMessageDTO> newMessage(@RequestBody ChatMessageDTO chatMessageDTO, Principal principal) {
|
public ResponseEntity<ChatMessageDTO> newMessage(@RequestBody ChatMessageDTO chatMessageDTO, Principal principal) {
|
||||||
MessageCipher messageCipher = chatMessageDTO.getMessageCipher();
|
MessageCipherDTO messageCipher = chatMessageDTO.getMessageCipher();
|
||||||
String fromUser = principal.getName();
|
String fromUser = principal.getName();
|
||||||
String toUser = chatMessageDTO.getToUser();
|
String toUser = chatMessageDTO.getToUser();
|
||||||
System.out.println("Message cipher = " + messageCipher);
|
System.out.println("Message cipher = " + messageCipher);
|
||||||
@ -48,9 +51,19 @@ public class ChatMessageController {
|
|||||||
List<ChatMessageDTO> chatMessageDTOs = chatService.getAllMessages(principal.getName(), userName);
|
List<ChatMessageDTO> chatMessageDTOs = chatService.getAllMessages(principal.getName(), userName);
|
||||||
return chatMessageDTOs;
|
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}")
|
@GetMapping(value = "/get/messages/{userName}/{lastMessageTime}")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName, @PathVariable String lastMessageTime, Principal principal) {
|
public List<ChatMessageDTO> sendNewMessages(@PathVariable String userName, @PathVariable String lastMessageTime,
|
||||||
|
Principal principal) {
|
||||||
System.out.println("Last message time = " + lastMessageTime);
|
System.out.println("Last message time = " + lastMessageTime);
|
||||||
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
|
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
|
||||||
// date/time
|
// date/time
|
||||||
@ -68,9 +81,9 @@ public class ChatMessageController {
|
|||||||
List<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages(principal.getName(), userName, date);
|
List<ChatMessageDTO> chatMessageDTOs = chatService.getNewMessages(principal.getName(), userName, date);
|
||||||
return chatMessageDTOs;
|
return chatMessageDTOs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get/users")
|
@GetMapping("/get/users")
|
||||||
public List<String> getAllOtherUsers(Principal principal)
|
public List<String> getAllOtherUsers(Principal principal) {
|
||||||
{
|
|
||||||
return userService.findAllOtherUsers(principal.getName());
|
return userService.findAllOtherUsers(principal.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,23 +70,25 @@ public class DemoRestController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/roles")
|
@GetMapping("/roles")
|
||||||
public List<UserRole> getAllRoles()
|
public List<UserRole> getAllRoles() {
|
||||||
{
|
|
||||||
return userRoleRepository.findAll();
|
return userRoleRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/ciphers")
|
@GetMapping("/ciphers")
|
||||||
public List<MessageCipher> getAllCiphers()
|
public List<MessageCipher> getAllCiphers() {
|
||||||
{
|
|
||||||
return messageCipherRepository.findAll();
|
return messageCipherRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/messages")
|
@GetMapping("/messages")
|
||||||
public List<ChatMessage> getAllMessages()
|
public List<ChatMessage> getAllMessages() {
|
||||||
{
|
|
||||||
return chatMessageRepository.findAll();
|
return chatMessageRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/regular-users")
|
||||||
|
public List<String> getAllRegularUsers() {
|
||||||
|
return userRoleRepository.getAllRegularUser();
|
||||||
|
}
|
||||||
|
|
||||||
// @RequestMapping(value = "/", method = RequestMethod.POST)
|
// @RequestMapping(value = "/", method = RequestMethod.POST)
|
||||||
// public ResponseEntity<Car> update(@RequestBody Car car) {
|
// public ResponseEntity<Car> update(@RequestBody Car car) {
|
||||||
//
|
//
|
||||||
@ -99,19 +101,18 @@ public class DemoRestController {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
@PostMapping(value = "/post-message", consumes = { "application/json" })
|
@PostMapping(value = "/post-message", consumes = { "application/json" })
|
||||||
public ResponseEntity<MessageCipher> postMessage(@RequestBody MessageCipher messageCipher)
|
public ResponseEntity<MessageCipher> postMessage(@RequestBody MessageCipher messageCipher) {
|
||||||
{
|
|
||||||
System.out.println("Message cipher = " + messageCipher);
|
System.out.println("Message cipher = " + messageCipher);
|
||||||
messageCipherRepository.save(messageCipher);
|
messageCipherRepository.save(messageCipher);
|
||||||
return new ResponseEntity<MessageCipher>(HttpStatus.OK);
|
return new ResponseEntity<MessageCipher>(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/logout")
|
@GetMapping("/logout")
|
||||||
public ModelAndView logoutPage()
|
public ModelAndView logoutPage() {
|
||||||
{
|
|
||||||
ModelAndView modelAndView = new ModelAndView("restLogout");
|
ModelAndView modelAndView = new ModelAndView("restLogout");
|
||||||
return modelAndView;
|
return modelAndView;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "perform_logout", method = RequestMethod.POST)
|
@RequestMapping(value = "perform_logout", method = RequestMethod.POST)
|
||||||
public String performLogout(HttpServletRequest request, HttpServletResponse response) {
|
public String performLogout(HttpServletRequest request, HttpServletResponse response) {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
@ -1,34 +1,37 @@
|
|||||||
package org.ros.chatto.controller;
|
package org.ros.chatto.controller;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.validation.Valid;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.ros.chatto.dto.UserRegistrationDTO;
|
import org.ros.chatto.dto.UserRegistrationDTO;
|
||||||
import org.ros.chatto.service.UserService;
|
import org.ros.chatto.service.UserService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class RegisterController {
|
public class RegistrationController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
@GetMapping("/registration")
|
@GetMapping("/registration")
|
||||||
public ModelAndView registrationForm()
|
public String registrationForm(Model model) {
|
||||||
{
|
model.addAttribute("userRegistrationDTO", new UserRegistrationDTO());
|
||||||
ModelAndView modelAndView = new ModelAndView("registration");
|
return "registration";
|
||||||
modelAndView.addObject("userDTO",new UserRegistrationDTO());
|
|
||||||
return modelAndView;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/perform_registration")
|
@PostMapping("/perform_registration")
|
||||||
public ModelAndView performRegistration(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, @ModelAttribute("userDTO") UserRegistrationDTO userRegistrationDTO)
|
public String performRegistration(Model model,
|
||||||
{
|
@ModelAttribute("userRegistrationDTO") @Valid UserRegistrationDTO userRegistrationDTO, BindingResult bindingResult) {
|
||||||
ModelAndView modelAndView = new ModelAndView("user/home");
|
if (bindingResult.hasErrors()) {
|
||||||
|
System.out.println("Input has errors!");
|
||||||
|
return "registration";
|
||||||
|
}
|
||||||
userService.registerUser(userRegistrationDTO);
|
userService.registerUser(userRegistrationDTO);
|
||||||
return modelAndView;
|
return "user/home";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class ChatMessageDTO {
|
public class ChatMessageDTO {
|
||||||
private String toUser, fromUser;
|
private String toUser, fromUser;
|
||||||
private MessageCipher messageCipher;
|
private MessageCipherDTO messageCipher;
|
||||||
private Date messageTime;
|
private Date messageTime;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.ros.chatto.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class MessageCipherDTO {
|
||||||
|
private String iv;
|
||||||
|
private int v;
|
||||||
|
@JsonProperty("iter")
|
||||||
|
private int iterations;
|
||||||
|
@JsonProperty("ks")
|
||||||
|
private int keySize;
|
||||||
|
@JsonProperty("ts")
|
||||||
|
private int tagSize;
|
||||||
|
private String mode;
|
||||||
|
private String adata;
|
||||||
|
private String cipher;
|
||||||
|
private String salt;
|
||||||
|
@JsonProperty("ct")
|
||||||
|
private String cipherText;
|
||||||
|
}
|
14
chatto/src/main/java/org/ros/chatto/dto/ReencryptionDTO.java
Normal file
14
chatto/src/main/java/org/ros/chatto/dto/ReencryptionDTO.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package org.ros.chatto.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.ros.chatto.model.MessageCipher;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ReencryptionDTO {
|
||||||
|
private String toUser, fromUser;
|
||||||
|
private MessageCipher messageCipher;
|
||||||
|
private Date messageTime;
|
||||||
|
}
|
@ -1,14 +0,0 @@
|
|||||||
package org.ros.chatto.dto;
|
|
||||||
|
|
||||||
import java.sql.Date;
|
|
||||||
|
|
||||||
import org.ros.chatto.model.MessageCipher;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class UserPublicDTO {
|
|
||||||
String fromUser, toUser;
|
|
||||||
MessageCipher messageCipher;
|
|
||||||
Date messageTime;
|
|
||||||
}
|
|
@ -1,23 +1,35 @@
|
|||||||
package org.ros.chatto.dto;
|
package org.ros.chatto.dto;
|
||||||
|
|
||||||
import javax.persistence.Transient;
|
import javax.persistence.Transient;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
public class UserRegistrationDTO {
|
public class UserRegistrationDTO {
|
||||||
|
@Size(min = 4, max = 10, message = "Username must be between 4 and 10 characters")
|
||||||
|
@NotBlank(message = " Username should not be blank")
|
||||||
|
@Pattern(regexp = "^[A-Za-z0-9]+$", message = "Username must be alphanumeric")
|
||||||
private String userName;
|
private String userName;
|
||||||
@Transient
|
@Transient
|
||||||
|
@Size(min = 4, max = 75, message = "Username must be between 4 and 75 characters")
|
||||||
|
@NotBlank(message = " Password should not be blank")
|
||||||
|
@Pattern(regexp = "^.*(?=.{6,})(?=.*d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$", message = "Invalid password format")
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
public String getUserName() {
|
public String getUserName() {
|
||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserName(String userName) {
|
public void setUserName(String userName) {
|
||||||
this.userName = userName;
|
this.userName = userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(String password) {
|
public void setPassword(String password) {
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package org.ros.chatto.model;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Table(name="status")
|
||||||
|
public class ApplicationStatus {
|
||||||
|
@Id
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
@Column(name="value")
|
||||||
|
private boolean done;
|
||||||
|
}
|
@ -20,7 +20,7 @@ this is what the json will look like*/
|
|||||||
@Entity
|
@Entity
|
||||||
@Table(name = "message_ciphers")
|
@Table(name = "message_ciphers")
|
||||||
@EntityListeners(AuditingEntityListener.class)
|
@EntityListeners(AuditingEntityListener.class)
|
||||||
@JsonIgnoreProperties(value = { "id"}, allowGetters = false)
|
//@JsonIgnoreProperties(value = { "id"}, allowGetters = false)
|
||||||
public class MessageCipher {
|
public class MessageCipher {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package org.ros.chatto.repository;
|
package org.ros.chatto.repository;
|
||||||
|
|
||||||
|
import java.awt.print.Pageable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.ros.chatto.model.ChatMessage;
|
import org.ros.chatto.model.ChatMessage;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.Query;
|
import org.springframework.data.jpa.repository.Query;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
@ -22,4 +24,14 @@ public interface ChatMessageRepository extends JpaRepository<ChatMessage, Long>
|
|||||||
+ "(m.fromUser.userName = ?1 or m.fromUser.userName = ?2) and"
|
+ "(m.fromUser.userName = ?1 or m.fromUser.userName = ?2) and"
|
||||||
+ "(m.messageTime > ?3) order by m.messageTime asc")
|
+ "(m.messageTime > ?3) order by m.messageTime asc")
|
||||||
public List<ChatMessage> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
public List<ChatMessage> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
||||||
|
|
||||||
|
@Query("select m from ChatMessage m where (m.toUser.userName = ?1 or m.toUser.userName = ?2) and "
|
||||||
|
+ "(m.fromUser.userName = ?1 or m.fromUser.userName = ?2) order by m.messageTime asc")
|
||||||
|
public List<ChatMessage> getAllMessages(String fromUser, String toUser, PageRequest pageRequest);
|
||||||
|
|
||||||
|
|
||||||
|
// DELETE FROM Country c WHERE c.population < :p
|
||||||
|
// @Query("delete from ChatMessage m where where (m.toUser.userName = ?1 or m.toUser.userName = ?2) and"
|
||||||
|
// + " (m.fromUser.userName = ?1 or m.fromUser.userName = ?2)")
|
||||||
|
// public void deleteConversation(String fromUser, String toUser);
|
||||||
}
|
}
|
||||||
|
@ -14,4 +14,7 @@ public interface UserRoleRepository extends JpaRepository<UserRole, Long>{
|
|||||||
|
|
||||||
@Query("select ur from UserRole ur where ur.user.userName = ?1")
|
@Query("select ur from UserRole ur where ur.user.userName = ?1")
|
||||||
public List<UserRole> findByUser(String username);
|
public List<UserRole> findByUser(String username);
|
||||||
|
|
||||||
|
@Query("select ur.user.userName from UserRole ur where ur.role.roleID = 2")
|
||||||
|
public List<String> getAllRegularUser();
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,23 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.ros.chatto.dto.ChatMessageDTO;
|
import org.ros.chatto.dto.ChatMessageDTO;
|
||||||
import org.ros.chatto.model.MessageCipher;
|
import org.ros.chatto.dto.MessageCipherDTO;
|
||||||
|
import org.ros.chatto.dto.ReencryptionDTO;
|
||||||
|
import org.ros.chatto.model.ChatMessage;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
|
||||||
public interface ChatService {
|
public interface ChatService {
|
||||||
void saveNewMessage(String fromUser, String toUser , MessageCipher messageCipher);
|
public void saveNewMessage(String fromUser, String toUser, MessageCipherDTO messageCipherDTO);
|
||||||
|
|
||||||
List<ChatMessageDTO> getAllMessages(String fromUser, String toUser);
|
public List<ChatMessageDTO> getAllMessages(String fromUser, String toUser);
|
||||||
|
|
||||||
List<ChatMessageDTO> getMessagePage(int page, int size);
|
public List<ChatMessageDTO> getMessagePage(String fromUser, String toUser, int page, int size);
|
||||||
|
|
||||||
List<ChatMessageDTO> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
public List<ChatMessageDTO> getNewMessages(String fromUser, String toUser, Date lastMessageTime);
|
||||||
|
|
||||||
|
public void reencryptMessages(List<ReencryptionDTO> reencryptionDTOs);
|
||||||
|
|
||||||
|
public List<ReencryptionDTO> getAllMessagesForReencryption(String fromUser, String toUser);
|
||||||
|
|
||||||
|
public List<ChatMessageDTO> getAllMessages(String name, String userName, PageRequest pageRequest);
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,13 @@ package org.ros.chatto.service;
|
|||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
import org.ros.chatto.dto.ChatMessageDTO;
|
import org.ros.chatto.dto.ChatMessageDTO;
|
||||||
|
import org.ros.chatto.dto.MessageCipherDTO;
|
||||||
|
import org.ros.chatto.dto.ReencryptionDTO;
|
||||||
import org.ros.chatto.model.ChatMessage;
|
import org.ros.chatto.model.ChatMessage;
|
||||||
import org.ros.chatto.model.ChatUser;
|
import org.ros.chatto.model.ChatUser;
|
||||||
import org.ros.chatto.model.MessageCipher;
|
import org.ros.chatto.model.MessageCipher;
|
||||||
@ -29,8 +34,9 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
MyConversionService myConversionService;
|
MyConversionService myConversionService;
|
||||||
|
|
||||||
public void saveNewMessage(String fromUserName, String toUserName, MessageCipher messageCipher) {
|
public void saveNewMessage(String fromUserName, String toUserName, MessageCipherDTO messageCipherDTO) {
|
||||||
|
|
||||||
|
MessageCipher messageCipher = myConversionService.convertToMessageCipher(messageCipherDTO);
|
||||||
ChatUser fromUser = userRepository.findByUserName(fromUserName);
|
ChatUser fromUser = userRepository.findByUserName(fromUserName);
|
||||||
ChatUser toUser = userRepository.findByUserName(toUserName);
|
ChatUser toUser = userRepository.findByUserName(toUserName);
|
||||||
ChatMessage chatMessage = new ChatMessage();
|
ChatMessage chatMessage = new ChatMessage();
|
||||||
@ -51,11 +57,17 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ChatMessageDTO> getMessagePage(int page, int size) {
|
public List<ReencryptionDTO> getAllMessagesForReencryption(String fromUser, String toUser) {
|
||||||
|
return myConversionService.convertToReencryptionDTOs(chatMessageRepository.getAllMessages(fromUser, toUser));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ChatMessageDTO> getMessagePage(String fromUser, String toUser, int page, int size) {
|
||||||
// Sort sort = Sort
|
// Sort sort = Sort
|
||||||
Page<ChatMessage> chatMessages = chatMessageRepository.findAll(PageRequest.of(page, size));
|
// Page<ChatMessage> chatMessages = chatMessageRepository.getAllMessages(fromUser, toUser,PageRequest.of(page, size));
|
||||||
List<ChatMessageDTO> chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages);
|
// List<ChatMessageDTO> chatMessageDTOs = myConversionService.convertToChatMessageDTOs(chatMessages);
|
||||||
return chatMessageDTOs;
|
// return chatMessageDTOs;
|
||||||
|
return myConversionService.convertToChatMessageDTOs(chatMessageRepository.getAllMessages(fromUser, toUser,PageRequest.of(page, size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,4 +77,20 @@ public class ChatServiceImpl implements ChatService {
|
|||||||
// List<ChatMessageDTO> chatMessageDTOs
|
// List<ChatMessageDTO> chatMessageDTOs
|
||||||
return myConversionService.convertToChatMessageDTOs(chatMessages);
|
return myConversionService.convertToChatMessageDTOs(chatMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void reencryptMessages(List<ReencryptionDTO> reencryptionDTOs) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// chatMessageRepository.saveAll(chatMessages);
|
||||||
|
List<MessageCipher> messageCiphers = reencryptionDTOs.stream().map(reencryptionDTO -> reencryptionDTO.getMessageCipher()).collect(Collectors.toList());
|
||||||
|
messageCipherRepository.saveAll(messageCiphers);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ChatMessageDTO> getAllMessages(String name, String userName, PageRequest pageRequest) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package org.ros.chatto.service;
|
|||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@ -10,9 +9,15 @@ import java.sql.DriverManager;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.ros.chatto.ChattoApplication;
|
import javax.persistence.EntityManager;
|
||||||
|
import javax.persistence.PersistenceContext;
|
||||||
|
|
||||||
|
import org.ros.chatto.model.ApplicationStatus;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
import org.springframework.context.annotation.PropertySource;
|
import org.springframework.context.annotation.PropertySource;
|
||||||
@ -51,6 +56,12 @@ public class DBInitializerService {
|
|||||||
|
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
|
@PersistenceContext
|
||||||
|
EntityManager entityManager;
|
||||||
|
|
||||||
|
private final String tablesCreatedKey = "tables_created";
|
||||||
|
private final String rolesPopulatedKey = "roles_populated";
|
||||||
|
|
||||||
// public DBInitializerService(Connection connection) {
|
// public DBInitializerService(Connection connection) {
|
||||||
// this.connection = connection;
|
// this.connection = connection;
|
||||||
// // TODO Auto-generated constructor stub
|
// // TODO Auto-generated constructor stub
|
||||||
@ -125,9 +136,29 @@ public class DBInitializerService {
|
|||||||
@EventListener(ApplicationReadyEvent.class)
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
public void doSomethingAfterStartup() throws SQLException, IOException {
|
public void doSomethingAfterStartup() throws SQLException, IOException {
|
||||||
// setProperties();
|
// setProperties();
|
||||||
|
|
||||||
System.out.println("Hello world, I have just started up");
|
System.out.println("Hello world, I have just started up");
|
||||||
System.out.println("Initializing database");
|
|
||||||
|
List<ApplicationStatus> applicationStatusList = getStatusList();
|
||||||
|
Map<String, Boolean> statusMap = listToMap(applicationStatusList);
|
||||||
|
|
||||||
|
// applicationStatus.
|
||||||
connectDB();
|
connectDB();
|
||||||
|
/*
|
||||||
|
* if (statusMap.get(tablesCreatedKey) == null ||
|
||||||
|
* !statusMap.get(tablesCreatedKey)) {
|
||||||
|
* System.out.println("Initializing database"); if (getNumTables() == 0) {
|
||||||
|
* populateDB(); System.out.println("Tables created"); } ApplicationStatus
|
||||||
|
* status = new ApplicationStatus(); status.setName(tablesCreatedKey);
|
||||||
|
* status.setDone(true);
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (statusMap.get(rolesPopulatedKey) == null ||
|
||||||
|
* !statusMap.get(rolesPopulatedKey)) { System.out.println("Populating roles");
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
if (getNumTables() == 0)
|
if (getNumTables() == 0)
|
||||||
populateDB();
|
populateDB();
|
||||||
closeConnection();
|
closeConnection();
|
||||||
@ -191,6 +222,23 @@ public class DBInitializerService {
|
|||||||
// prop.store(object, comments);
|
// prop.store(object, comments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<ApplicationStatus> getStatusList() {
|
||||||
|
// List<Object[]> persons = entityManager.createNativeQuery("SELECT * FROM Person" ).getResultList();
|
||||||
|
List<ApplicationStatus> applicationStatus = entityManager
|
||||||
|
.createQuery("from ApplicationStatus s", ApplicationStatus.class).getResultList();
|
||||||
|
applicationStatus.stream().forEach(status -> status.getName());
|
||||||
|
// System.out.println(applicationStatus.get(0).getName() + applicationStatus.get(0).isDone());
|
||||||
|
return applicationStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Boolean> listToMap(List<ApplicationStatus> applicationStatusList) {
|
||||||
|
Map<String, Boolean> statusMap = new HashMap<>();
|
||||||
|
for (ApplicationStatus applicationStatus : applicationStatusList) {
|
||||||
|
statusMap.put(applicationStatus.getName(), applicationStatus.isDone());
|
||||||
|
}
|
||||||
|
return statusMap;
|
||||||
|
}
|
||||||
|
|
||||||
public void closeConnection() throws SQLException {
|
public void closeConnection() throws SQLException {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,10 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
import org.ros.chatto.dto.ChatMessageDTO;
|
import org.ros.chatto.dto.ChatMessageDTO;
|
||||||
|
import org.ros.chatto.dto.MessageCipherDTO;
|
||||||
|
import org.ros.chatto.dto.ReencryptionDTO;
|
||||||
import org.ros.chatto.model.ChatMessage;
|
import org.ros.chatto.model.ChatMessage;
|
||||||
|
import org.ros.chatto.model.MessageCipher;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -42,6 +45,18 @@ public class MyConversionService {
|
|||||||
return chatMessageDTO;
|
return chatMessageDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ChatMessage convertToChatMessage(ChatMessageDTO chatMessageDTO)
|
||||||
|
{
|
||||||
|
ChatMessage chatMessage = modelMapper.map(chatMessageDTO, ChatMessage.class);
|
||||||
|
return chatMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MessageCipher convertToMessageCipher(MessageCipherDTO messageCipherDTO)
|
||||||
|
{
|
||||||
|
MessageCipher messageCipher = modelMapper.map(messageCipherDTO, MessageCipher.class);
|
||||||
|
return messageCipher;
|
||||||
|
}
|
||||||
|
|
||||||
public List<ChatMessageDTO> convertToChatMessageDTOs(List<ChatMessage> chatMessages)
|
public List<ChatMessageDTO> convertToChatMessageDTOs(List<ChatMessage> chatMessages)
|
||||||
{
|
{
|
||||||
return chatMessages.stream()
|
return chatMessages.stream()
|
||||||
@ -49,6 +64,33 @@ public class MyConversionService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReencryptionDTO convertToReencryptionDTO(ChatMessage chatMessage)
|
||||||
|
{
|
||||||
|
ReencryptionDTO reencryptionDTO = modelMapper.map(chatMessage, ReencryptionDTO.class);
|
||||||
|
return reencryptionDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatMessage convertToChatMessage(ReencryptionDTO reencryptionDTO)
|
||||||
|
{
|
||||||
|
ChatMessage chatMessage = modelMapper.map(reencryptionDTO, ChatMessage.class);
|
||||||
|
return chatMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ReencryptionDTO> convertToReencryptionDTOs(List<ChatMessage> chatMessages)
|
||||||
|
{
|
||||||
|
return chatMessages.stream()
|
||||||
|
.map(chatMessage -> convertToReencryptionDTO(chatMessage))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Iterable<ChatMessage> convertoToChatMessages(List<ChatMessageDTO> chatMessageDTOs)
|
||||||
|
{
|
||||||
|
|
||||||
|
return chatMessageDTOs.stream()
|
||||||
|
.map(chatMessageDTO -> convertToChatMessage(chatMessageDTO)).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
public List<ChatMessageDTO> convertToChatMessageDTOs(Page<ChatMessage> chatMessages)
|
public List<ChatMessageDTO> convertToChatMessageDTOs(Page<ChatMessage> chatMessages)
|
||||||
{
|
{
|
||||||
return chatMessages.stream()
|
return chatMessages.stream()
|
||||||
|
@ -11,4 +11,5 @@ public interface UserService {
|
|||||||
public void saveChatUser(ChatUser user);
|
public void saveChatUser(ChatUser user);
|
||||||
public List<String> findAllOtherUsers(String userName);
|
public List<String> findAllOtherUsers(String userName);
|
||||||
public void registerUser(UserRegistrationDTO userRegistrationDTO);
|
public void registerUser(UserRegistrationDTO userRegistrationDTO);
|
||||||
|
public List<String> getAllRegularUsers();
|
||||||
}
|
}
|
||||||
|
@ -62,4 +62,10 @@ public class UserServiceImpl implements UserService{
|
|||||||
return userRepositoryCustom.getAllUserNames(userName);
|
return userRepositoryCustom.getAllUserNames(userName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getAllRegularUsers() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return userRoleRepository.getAllRegularUser();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
num-tables = SELECT COUNT(*) as num_tables FROM information_schema.tables WHERE table_schema = ? and TABLE_TYPE='BASE TABLE'
|
num-tables = SELECT COUNT(*) as num_tables FROM information_schema.tables WHERE table_schema = ? and TABLE_TYPE='BASE TABLE'
|
||||||
|
#tables-created =
|
135
chatto/src/main/resources/static/js/admin.js
Normal file
135
chatto/src/main/resources/static/js/admin.js
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
console.log('Hello world!');
|
||||||
|
|
||||||
|
var getAllMessagesURL = `http://${hostAddress}/api/admin/get/messages/`; //hostAddress set in thymeleaf backend
|
||||||
|
var reencryptURL = `http://${hostAddress}/api/admin/post/re-encrypt`;
|
||||||
|
var getAllRegularUsersURL = `http://${hostAddress}/api/regular-users`;
|
||||||
|
var username = sessionStorage.getItem('username');
|
||||||
|
var password = sessionStorage.getItem('password');
|
||||||
|
var authToken = 'Basic ' + btoa(username + ":" + password);
|
||||||
|
var iterations = 10000;
|
||||||
|
|
||||||
|
function handleAddToAdminForm() {
|
||||||
|
document.getElementById('addUserToAdminForm').addEventListener(
|
||||||
|
'submit',
|
||||||
|
function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
getAllRegularUsers()
|
||||||
|
// .then(usernamesArray => {
|
||||||
|
// console.lo
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleChangePassphraseForm() {
|
||||||
|
document.getElementById('changePassphraseForm').addEventListener(
|
||||||
|
'submit',
|
||||||
|
function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let changePassphraseDropDown = document.getElementById('changePassphraseDropDown');
|
||||||
|
let user = changePassphraseDropDown.value;
|
||||||
|
let passphraseOld = document.getElementById('passphraseOld');
|
||||||
|
let passphraseNew = document.getElementById('passphraseNew');
|
||||||
|
// let messageCipherNew = {};
|
||||||
|
console.log(user);
|
||||||
|
getAllMessages(user)
|
||||||
|
.then(json => {
|
||||||
|
console.log(json);
|
||||||
|
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
let jsonNew = [];
|
||||||
|
let messageCiphers = [];
|
||||||
|
let chatMessageDTOs = [];
|
||||||
|
if (json.length > 0) {
|
||||||
|
json.forEach(function(obj) {
|
||||||
|
let newObj = obj;
|
||||||
|
let messageID = obj.messageCipher.id;
|
||||||
|
let plainText = sjcl.decrypt(passphraseOld.value, JSON.stringify(obj.messageCipher));
|
||||||
|
let messageCipherNew = sjcl.encrypt(passphraseNew.value, plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||||
|
// let plainText = sjcl.decrypt("password", JSON.stringify(obj.messageCipher));
|
||||||
|
// let messageCipherNew = sjcl.encrypt("password2", plainText, { mode: "gcm", ts: 128, adata: "", iter: iterations });
|
||||||
|
// console.log(messageCipherNew)
|
||||||
|
let messageCipherNewObj = JSON.parse(messageCipherNew);
|
||||||
|
// console.log(messageCipherNewObj);
|
||||||
|
messageCipherNewObj.id = messageID;
|
||||||
|
newObj.messageCipher = messageCipherNewObj;
|
||||||
|
// obj.messageCipher = messageCipherNewObj;
|
||||||
|
// console.log(obj.messageCipher);
|
||||||
|
// console.log(plainText);
|
||||||
|
// console.log(messageCipherNewObj);
|
||||||
|
jsonNew.push(newObj);
|
||||||
|
messageCiphers.push(messageCipherNewObj);
|
||||||
|
|
||||||
|
// let messageCipherJson = JSON.stringify(messageCipherNewObj);
|
||||||
|
let fromUser = sessionStorage.getItem('username');
|
||||||
|
let chatMessageDTO = {
|
||||||
|
"toUser": user,
|
||||||
|
"fromUser": username,
|
||||||
|
"messageCipher": messageCipherNewObj
|
||||||
|
}
|
||||||
|
chatMessageDTOs.push(chatMessageDTO);
|
||||||
|
});
|
||||||
|
// console.log(jsonNew);
|
||||||
|
|
||||||
|
}
|
||||||
|
// sendReencryptedMessages(JSON.stringify(jsonNew));
|
||||||
|
console.log
|
||||||
|
sendReencryptedMessages(JSON.stringify(chatMessageDTOs));
|
||||||
|
// sendReencryptedMessages(JSON.stringify(messageCiphers));
|
||||||
|
|
||||||
|
return jsonNew;
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
json.forEach(function(obj) {
|
||||||
|
let plainText = sjcl.decrypt("password2", JSON.stringify(obj.messageCipher));
|
||||||
|
console.log(plainText);
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllMessages(user) {
|
||||||
|
let headers = new Headers();
|
||||||
|
// headers.append('Accept','application/json')
|
||||||
|
// headers.append('Content-Type', 'application/json');
|
||||||
|
headers.append('Authorization', authToken);
|
||||||
|
let response = await fetch(`${getAllMessagesURL}${user}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: headers
|
||||||
|
});
|
||||||
|
let data = await response.json();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getAllRegularUsers() {
|
||||||
|
let headers = new Headers();
|
||||||
|
// headers.append('Accept','application/json')
|
||||||
|
// headers.append('Content-Type', 'application/json');
|
||||||
|
headers.append('Authorization', authToken);
|
||||||
|
let response = await fetch(`${getAllRegularUsersURL}`, {
|
||||||
|
method: 'GET',
|
||||||
|
headers: headers
|
||||||
|
});
|
||||||
|
let data = await response.json();
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendReencryptedMessages(chatMessageDTOs) {
|
||||||
|
let headers = new Headers();
|
||||||
|
// console.log("Token = " + btoa("hmm" + ":" + "hmm"))
|
||||||
|
|
||||||
|
// headers.append('Accept','application/json')
|
||||||
|
headers.append('Content-Type', 'application/json');
|
||||||
|
headers.append('Authorization', authToken);
|
||||||
|
fetch(reencryptURL, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: headers,
|
||||||
|
body: chatMessageDTOs
|
||||||
|
})
|
||||||
|
.then(response => console.log(response));
|
||||||
|
}
|
||||||
|
|
||||||
|
handleAddToAdminForm();
|
||||||
|
handleChangePassphraseForm();
|
@ -52,10 +52,20 @@ function getSelectedUser() {
|
|||||||
|
|
||||||
function handleChatForm() {
|
function handleChatForm() {
|
||||||
let chatInput = document.getElementById('chatInput');
|
let chatInput = document.getElementById('chatInput');
|
||||||
let myForm = document.getElementById('chatMessageForm').addEventListener(
|
let myForm = document.getElementById('chatMessageForm');
|
||||||
'submit', function (e) {
|
myForm.addEventListener(
|
||||||
|
'submit',
|
||||||
|
function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let user = getSelectedUser();
|
let user = getSelectedUser();
|
||||||
|
|
||||||
|
if (!myForm.checkValidity()) {
|
||||||
|
console.log("error");
|
||||||
|
myForm.classList.add('was-validated');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
myForm.classList.add('was-validated');
|
||||||
|
|
||||||
if (!isCheckedUser) {
|
if (!isCheckedUser) {
|
||||||
window.alert('please select a user');
|
window.alert('please select a user');
|
||||||
return;
|
return;
|
||||||
@ -235,8 +245,7 @@ parent.addDelegatedListener("click", "input[type='radio']", function (event) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
|
|
||||||
console.log("Stored messages = " + sessionStorage.getItem(this.value));
|
console.log("Stored messages = " + sessionStorage.getItem(this.value));
|
||||||
@ -302,4 +311,3 @@ parent.addDelegatedListener("click", "input[type='radio']", function (event) {
|
|||||||
|
|
||||||
|
|
||||||
handleChatForm();
|
handleChatForm();
|
||||||
|
|
||||||
|
@ -1,13 +1,110 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<div th:replace="fragments/head :: headFragment">
|
||||||
<title>Insert title here</title>
|
<title id="pageTitle">Admin Home</title>
|
||||||
|
</div>
|
||||||
|
<script src="https://code.jquery.com/jquery-2.1.4.min.js" th:if="false"></script>
|
||||||
|
<script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js" data-template-prefix="../" defer="defer" th:if="false"></script>
|
||||||
|
<script th:src="@{js/admin.js}" src="../../static/js/admin.js" defer="defer"></script>
|
||||||
|
<link th:href="@{/css/master.css}" href="../../static/css/master.css" rel="stylesheet" th:if="false">
|
||||||
|
<link th:href="@{/css/colors.css}" href="../../static/css/colors.css" rel="stylesheet" th:if="false">
|
||||||
</head>
|
</head>
|
||||||
|
<!-- TODO
|
||||||
|
Make user admin / remove user from admin
|
||||||
|
Change E2E passphrase
|
||||||
|
Delete Messages
|
||||||
|
-->
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
admin page
|
<div th:include="fragments/navbar :: navbarFragment"></div>
|
||||||
<form action="#" th:action="@{/perform_logout}" method="POST">
|
|
||||||
<input type="submit" value="logout">
|
<header>
|
||||||
|
<div class="container bg-primary">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm py-5">
|
||||||
|
<h1 class="display-4 text-center">Admin Page</h1>
|
||||||
|
<p class="alert-danger px-2">Warning: these settings can be dangerous..</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm col-md-4">
|
||||||
|
<h4>Make User an Admin</h4>
|
||||||
|
<form id="addUserToAdminForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="addUserToDropDown">Select User:</label>
|
||||||
|
<select class="form-control custom-select" size="4" id="addUserToAdminDropDown">
|
||||||
|
|
||||||
|
<option th:each="userName : ${userNames}"
|
||||||
|
th:value="${userName}"
|
||||||
|
th:text="#{${userName}}">
|
||||||
|
Wireframe
|
||||||
|
</option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-danger form-control">Make admin</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm col-md-4">
|
||||||
|
<h4>Change passphrases</h4>
|
||||||
|
<form id="changePassphraseForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="changePassphraseDropDown">Select User:</label>
|
||||||
|
<select class="form-control" id="changePassphraseDropDown">
|
||||||
|
|
||||||
|
<option th:each="userName : ${userNames}"
|
||||||
|
th:value="${userName}"
|
||||||
|
th:text="#{${userName}}">
|
||||||
|
Wireframe
|
||||||
|
</option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="passphraseOld">Passphrase Old</label>
|
||||||
|
<input type="password" id="passphraseOld" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="passphraseNew">Passphrase New</label>
|
||||||
|
<input type="password" id="passphraseNew" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-danger form-control">Change Passphrase</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<!-- <div class="col-sm"></div> -->
|
||||||
|
|
||||||
|
<div class="col-sm d-lg-block">
|
||||||
|
<div class="d-flex justify-content-center">
|
||||||
|
<div class="py-5">
|
||||||
|
<h4 class="p-2 text-center">Logout</h4>
|
||||||
|
<form action="#" th:action="@{/logout}" method="POST">
|
||||||
|
<!-- <input type="submit" value="logout"> -->
|
||||||
|
<!-- <input type="hidden" th:name="${_csrf.parameterName}"
|
||||||
|
th:value="${_csrf.token}" /> -->
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-secondary form-control">Logout</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -45,7 +45,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<h4 class="display-4 text-center py-2">Chat</h4>
|
<h4 class="display-4 text-center py-2">Chat</h4>
|
||||||
<div class="card text-white bg-primary mb-3 text-center card-form rounded mx-auto">
|
<div class="card text-white bg-primary mb-3 card-form rounded mx-auto">
|
||||||
|
|
||||||
<div class="card-body rounded">
|
<div class="card-body rounded">
|
||||||
<!-- <h4 class="card-title">Chat</h4> -->
|
<!-- <h4 class="card-title">Chat</h4> -->
|
||||||
@ -57,7 +57,7 @@
|
|||||||
<div class="card-text">
|
<div class="card-text">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<form action="#" th:object="${chatMessageDTO}" method="post" id="chatMessageForm">
|
<form action="#" th:object="${chatMessageDTO}" method="post" id="chatMessageForm" class="needs-validation" novalidate>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -74,14 +74,18 @@
|
|||||||
<div class="my-form-inputs container">
|
<div class="my-form-inputs container">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="chatInput">Your message: </label>
|
<label for="chatInput">Your message: </label>
|
||||||
<textarea class="form-control" type="text" id="chatInput"></textarea>
|
<textarea class="form-control" type="text" id="chatInput" required></textarea>
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
Cannot be empty
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="passphrase">Passphrase: </label>
|
<label for="passphrase">Passphrase: </label>
|
||||||
<input class="form-control" type="password" id="passphrase">
|
<input class="form-control" type="password" id="passphrase" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input class="form-control btn btn-secondary" type="submit" value="Send">
|
<button class="btn btn-secondary">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<div th:replace="fragments/head :: headFragment">
|
<div th:replace="fragments/head :: headFragment">
|
||||||
@ -34,13 +34,16 @@
|
|||||||
<a href="home.html" th:href="@{/}" class="nav-link">Home</a>
|
<a href="home.html" th:href="@{/}" class="nav-link">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="user/home.html" th:href="@{/user}" class="nav-link">User Area</a>
|
<a href="user/home.html" sec:authorize="isFullyAuthenticated()" th:href="@{/user}" class="nav-link">User Area</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a th:href="chat" href="chat.html" class="nav-link">Chat</a>
|
<a th:href="chat" href="chat.html" class="nav-link">Chat</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a th:href="login" href="login.html" class="nav-link">Login</a>
|
<a th:href="login" sec:authorize="!isFullyAuthenticated()" href="login.html" class="nav-link">Login</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="registration" sec:authorize="!isFullyAuthenticated()" href="registration.html" class="nav-link">Register</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="#" class="nav-link">About</a>
|
<a href="#" class="nav-link">About</a>
|
||||||
@ -48,7 +51,16 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="#" class="nav-link">Contact</a>
|
<a href="#" class="nav-link">Contact</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" sec:authorize="isFullyAuthenticated()" th:href="@{/admin}" class="nav-link">
|
||||||
|
Admin Area
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="#" sec:authorize="isFullyAuthenticated()" th:text="${#authentication.name}" class="nav-link text-white font-weight-bold">
|
||||||
|
nova
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<div th:replace="fragments/head :: headFragment">
|
<div th:replace="fragments/head :: headFragment">
|
||||||
@ -35,7 +35,7 @@
|
|||||||
<th:block th:each="userName: ${userNames}">
|
<th:block th:each="userName: ${userNames}">
|
||||||
<div th:text="${userName}"></div>
|
<div th:text="${userName}"></div>
|
||||||
</th:block> -->
|
</th:block> -->
|
||||||
<span th:if="${message}"> Welcome <span th:text="${message}"></span></span>
|
<span th:if="${message}"> </span> Welcome <span th:text="${#authentication.name}">nova</span>
|
||||||
<p>Chatto is a minimal, end to end encrypted chat application.</p>
|
<p>Chatto is a minimal, end to end encrypted chat application.</p>
|
||||||
<!-- <button class="btn btn-secondary"> <a href="registration.html" th:href="{@/registration}">Get Started</a></button> -->
|
<!-- <button class="btn btn-secondary"> <a href="registration.html" th:href="{@/registration}">Get Started</a></button> -->
|
||||||
<a class="btn btn-secondary" href="registration.html" th:href="@{/registration}">Get Started</a>
|
<a class="btn btn-secondary" href="registration.html" th:href="@{/registration}">Get Started</a>
|
||||||
@ -53,12 +53,14 @@
|
|||||||
<li>
|
<li>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
<!-- <i class="fas fa-check"></i> -->
|
<!-- <i class="fas fa-check"></i> -->
|
||||||
Self Hosted</p>
|
Self Hosted
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
<!-- <i class="fas fa-check"></i> -->
|
<!-- <i class="fas fa-check"></i> -->
|
||||||
End To End Encrypted Messaging</p>
|
End To End Encrypted Messaging
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
@ -68,7 +70,8 @@
|
|||||||
<li>
|
<li>
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
<!-- <i class="fas fa-check"></i> -->
|
<!-- <i class="fas fa-check"></i> -->
|
||||||
Built With Java And Spring</p>
|
Built With Java And Spring
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
</p>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<legend>Please Sign In</legend> -->
|
<legend>Please Sign In</legend> -->
|
||||||
<h2 class="card-title">Please Sign In</h2>
|
<h2 class="card-title">Please Sign In</h2>
|
||||||
<div th:if="${param.error}" class="alert alert-danger">
|
<div th:if="${param.error}" class="alert alert-danger">
|
||||||
Invalid username or password.
|
Error signing in. Please check your username and password.
|
||||||
</div>
|
</div>
|
||||||
<div th:if="${param.logout}" class="alert alert-success">
|
<div th:if="${param.logout}" class="alert alert-success">
|
||||||
You have been logged out.
|
You have been logged out.
|
||||||
|
@ -1,18 +1,73 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html xmlns:th="http://www.thymeleaf.org">
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<div th:replace="fragments/head :: headFragment">
|
||||||
<title>Insert title here</title>
|
<title id="pageTitle">Registration</title>
|
||||||
|
</div>
|
||||||
|
<script src="https://code.jquery.com/jquery-2.1.4.min.js" th:if="false"></script>
|
||||||
|
<script src="http://blackpeppersoftware.github.io/thymeleaf-fragment.js/thymeleaf-fragment.js" defer="defer" th:if="false"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<form action="#" th:action="@{/perform_registration}"
|
<div th:include="fragments/navbar :: navbarFragment"></div>
|
||||||
th:object=${userDTO} method="POST">
|
<header>
|
||||||
<label>Enter user name: </label> <input th:field="*{userName}"
|
<div class="container">
|
||||||
type="text" name="username" id="username"> <br> <br>
|
<div class="row">
|
||||||
<label>Enter password: </label> <input th:field="*{password}"
|
<div class="col-sm py-5">
|
||||||
type="password" name="password" id="password"> <br> <br>
|
<!-- <h4 class="display-4 text-center py-2">Chat</h4> -->
|
||||||
<input type="password" id="password-repeat">
|
<div class="card text-white bg-primary mb-3 text-center card-form rounded mx-auto" id="login-card">
|
||||||
<input type="submit" value="Submit">
|
|
||||||
|
<div class="card-body rounded">
|
||||||
|
<!-- <h4 class="card-title">Chat</h4> -->
|
||||||
|
<!-- <div class="form-group">
|
||||||
|
<textarea id="chatTextArea" class="form-control-lg py-2" disabled></textarea>
|
||||||
|
</div> -->
|
||||||
|
<!-- <form action="#" th:action="@{/seedstartermng}" th:object="${seedStarter}" method="post"> -->
|
||||||
|
<!-- th:action="@{/api/chat}" -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <label>First Name</label>
|
||||||
|
<div th:classappend="${#fields.hasErrors('firstName')} ? 'input-icon right' : ''">
|
||||||
|
<i th:if="${#fields.hasErrors('firstName')}" class="fa fa-exclamation tooltips" data-original-title="please enter a valid first name" data-container="body"></i>
|
||||||
|
<input type="text" class="form-control" maxlength="32" th:field="*{firstName}" placeholder="Between 1 and 32 characters" />
|
||||||
|
<span th:if="${#fields.hasErrors('firstName')}" class="help-block" th:errors="*{firstName}"></span>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div class="card-text">
|
||||||
|
<h2 class="card-title">Register</h2>
|
||||||
|
<form action="#" th:action="@{/perform_registration}" th:object=${userRegistrationDTO} method="POST">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Enter username: </label>
|
||||||
|
<div th:classappend="${#fields.hasErrors('userName')} ? 'input-icon right' : ''">
|
||||||
|
<i th:if="${#fields.hasErrors('userName')}" class="fa fa-exclamation tooltips" data-original-title="please enter a valid username" data-container="body"></i>
|
||||||
|
<input class="form-control" th:field="*{userName}" type="text" name="username" id="username" required>
|
||||||
|
<span th:if="${#fields.hasErrors('userName')}" class="help-block" th:errors="*{userName}"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Enter password: </label>
|
||||||
|
<i th:if="${#fields.hasErrors('password')}" class="fa fa-exclamation tooltips" data-original-title="please enter a valid first name" data-container="body"></i>
|
||||||
|
<input class="form-control" th:field="*{password}" type="password" name="password" id="password" required>
|
||||||
|
<span th:if="${#fields.hasErrors('password')}" class="help-block" th:errors="*{password}"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password-repeat">Repeat password: </label>
|
||||||
|
<input class="form-control" type="password" id="password-repeat" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input class="form-control btn btn-secondary" type="submit" value="Submit">
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user