mirror of
https://github.com/Lemonochrme/service-architecture.git
synced 2025-06-08 13:40:50 +02:00
db: Created "connections" table to store tokens. backend: created "/connect" endpoint.
This commit is contained in:
parent
e3ce964ae1
commit
2596c12178
6 changed files with 176 additions and 4 deletions
10
db/db.sql
10
db/db.sql
|
@ -5,6 +5,14 @@ CREATE TABLE `users` (
|
||||||
`password` text NOT NULL
|
`password` text NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
CREATE TABLE `connections` (
|
||||||
|
`id` integer UNIQUE PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`id_user` integer NOT NULL,
|
||||||
|
`token` varchar(128) UNIQUE NOT NULL,
|
||||||
|
`created_at` timestamp DEFAULT (now()),
|
||||||
|
`expires_at` timestamp
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE `roles` (
|
CREATE TABLE `roles` (
|
||||||
`id` integer UNIQUE PRIMARY KEY AUTO_INCREMENT,
|
`id` integer UNIQUE PRIMARY KEY AUTO_INCREMENT,
|
||||||
`name` text UNIQUE NOT NULL
|
`name` text UNIQUE NOT NULL
|
||||||
|
@ -30,6 +38,8 @@ CREATE TABLE `feedback` (
|
||||||
`message` text NOT NULL
|
`message` text NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ALTER TABLE `connections` ADD FOREIGN KEY (`id_user`) REFERENCES `users` (`id`);
|
||||||
|
|
||||||
ALTER TABLE `users` ADD FOREIGN KEY (`id_role`) REFERENCES `roles` (`id`);
|
ALTER TABLE `users` ADD FOREIGN KEY (`id_role`) REFERENCES `roles` (`id`);
|
||||||
|
|
||||||
ALTER TABLE `requests` ADD FOREIGN KEY (`id_user`) REFERENCES `users` (`id`);
|
ALTER TABLE `requests` ADD FOREIGN KEY (`id_user`) REFERENCES `users` (`id`);
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package insa.application.helpapp.rest;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "connections", schema = "service-architecture")
|
||||||
|
public class Connection {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@Column(name = "id_user", nullable = false)
|
||||||
|
private int idUser;
|
||||||
|
|
||||||
|
@Column(name = "token", nullable = false, unique = true, length = 128)
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Column(name = "created_at", nullable = false)
|
||||||
|
private LocalDateTime createdAt;
|
||||||
|
|
||||||
|
@Column(name = "expires_at", nullable = false)
|
||||||
|
private LocalDateTime expiresAt;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getidUser() {
|
||||||
|
return idUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setidUser(int idUser) {
|
||||||
|
this.idUser = idUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setToken(String token) {
|
||||||
|
this.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCreatedAt(LocalDateTime createdAt) {
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDateTime getExpiresAt() {
|
||||||
|
return expiresAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpiresAt(LocalDateTime expiresAt) {
|
||||||
|
this.expiresAt = expiresAt;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package insa.application.helpapp.rest;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ConnectionRepository extends JpaRepository<Connection, Integer> {
|
||||||
|
List<Connection> findByIdUser(int idUser);
|
||||||
|
}
|
|
@ -1,6 +1,19 @@
|
||||||
package insa.application.helpapp.rest;
|
package insa.application.helpapp.rest;
|
||||||
|
|
||||||
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.repository.query.Param;
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface UserRepository extends JpaRepository<User, Integer> {
|
public interface UserRepository extends JpaRepository<User, Integer> {
|
||||||
|
|
||||||
|
List<User> findByUsername(String username);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@Query("SELECT t FROM ConnectionToken t WHERE t.userId = :userId")
|
||||||
|
List<ConnectionToken> findCustomTokensByUserId(@Param("userId") int userId);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,38 @@ package insa.application.helpapp.rest;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
import org.hibernate.type.descriptor.java.LocalDateTimeJavaType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.List;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@RestController
|
@RestController
|
||||||
public class UserServiceApplication {
|
public class UserServiceApplication {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
@Autowired
|
||||||
|
private ConnectionRepository connectionRepository;
|
||||||
|
|
||||||
|
// https://stackoverflow.com/users/774398/patrick
|
||||||
|
public static String generateRandomBase64Token(int byteLength) {
|
||||||
|
SecureRandom secureRandom = new SecureRandom();
|
||||||
|
byte[] token = new byte[byteLength-32];
|
||||||
|
secureRandom.nextBytes(token);
|
||||||
|
return Base64.getUrlEncoder().withoutPadding().encodeToString(token); //base64 encoding
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(UserServiceApplication.class, args);
|
SpringApplication.run(UserServiceApplication.class, args);
|
||||||
|
@ -34,7 +55,7 @@ public class UserServiceApplication {
|
||||||
|
|
||||||
// Post should be : /create_user?idRole=1&username=toto&password=1234
|
// Post should be : /create_user?idRole=1&username=toto&password=1234
|
||||||
@PostMapping("/create_user")
|
@PostMapping("/create_user")
|
||||||
public User createUser(int idRole, String username, String password) {
|
public User createUser(@RequestParam int idRole, @RequestParam String username, @RequestParam String password) {
|
||||||
User user = new User();
|
User user = new User();
|
||||||
user.setIdRole(idRole);
|
user.setIdRole(idRole);
|
||||||
user.setUsername(username);
|
user.setUsername(username);
|
||||||
|
@ -43,4 +64,50 @@ public class UserServiceApplication {
|
||||||
return userRepository.save(user);
|
return userRepository.save(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Post should be : /connect?username=toto&password=1234
|
||||||
|
// Response can vary: Error if username/password doesn't exist/match
|
||||||
|
// Response if success: userId (int), expiresAt (time), token (varchar(128))
|
||||||
|
@PostMapping("/connect")
|
||||||
|
public ResponseEntity<?> connect(@RequestParam String username, @RequestParam String password)
|
||||||
|
{
|
||||||
|
List<User> users = userRepository.findByUsername(username);
|
||||||
|
// Checks username
|
||||||
|
if(users.isEmpty()) {
|
||||||
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Username not known.");
|
||||||
|
}
|
||||||
|
User user = users.getFirst();
|
||||||
|
// Checks password
|
||||||
|
if(!user.getPassword().equals(password)) {
|
||||||
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid password.");
|
||||||
|
}
|
||||||
|
// Checks if token already exists
|
||||||
|
List<Connection> connections = connectionRepository.findByIdUser(user.getId());
|
||||||
|
Map<String, Object> response = new HashMap<>();
|
||||||
|
Connection connection = new Connection();
|
||||||
|
if(!connections.isEmpty() && (connections.getFirst().getExpiresAt().isBefore(LocalDateTime.now())))
|
||||||
|
{
|
||||||
|
// Remove the old token
|
||||||
|
connectionRepository.delete(connections.getFirst());
|
||||||
|
// Create new token if password & username is correct
|
||||||
|
// Get User ID
|
||||||
|
connection.setidUser(user.getId());
|
||||||
|
// Generate token
|
||||||
|
connection.setToken(generateRandomBase64Token(128));
|
||||||
|
// Creation date and expiration date
|
||||||
|
connection.setCreatedAt(LocalDateTime.now());
|
||||||
|
connection.setExpiresAt(LocalDateTime.now().plusDays(1));
|
||||||
|
// Save created Connection
|
||||||
|
connectionRepository.save(connection);
|
||||||
|
} else {
|
||||||
|
connection = connections.getFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reponse to client
|
||||||
|
response.put("token", connection.getToken());
|
||||||
|
response.put("userId", connection.getidUser());
|
||||||
|
response.put("expiresAt", connection.getExpiresAt());
|
||||||
|
return ResponseEntity.ok(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,12 +43,12 @@ check_services() {
|
||||||
|
|
||||||
# Function to start services
|
# Function to start services
|
||||||
start_services() {
|
start_services() {
|
||||||
echo "" > ../process.tmp
|
echo "" > "$SCRIPT_DIR"/process.tmp
|
||||||
cd "$SCRIPT_DIR/helpapp-backend" || exit 1
|
cd "$SCRIPT_DIR/helpapp-backend" || exit 1
|
||||||
for service in "${services[@]}"; do
|
for service in "${services[@]}"; do
|
||||||
echo "> Starting $service..."
|
echo "> Starting $service..."
|
||||||
mvn spring-boot:run -pl "$service" > /dev/null 2>&1 &
|
mvn spring-boot:run -pl "$service" > /dev/null 2>&1 &
|
||||||
echo -e "$!" >> ../process.tmp
|
echo -e "$!" >> "$SCRIPT_DIR"/process.tmp
|
||||||
done
|
done
|
||||||
echo "> Waiting for the services to establish connection..."
|
echo "> Waiting for the services to establish connection..."
|
||||||
check_services
|
check_services
|
||||||
|
@ -63,6 +63,7 @@ stop_services() {
|
||||||
echo -e "\t> Killing process on port $port..."
|
echo -e "\t> Killing process on port $port..."
|
||||||
fuser -k $port/tcp
|
fuser -k $port/tcp
|
||||||
done
|
done
|
||||||
|
rm "$SCRIPT_DIR"/process.tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check command line arguments
|
# Check command line arguments
|
||||||
|
|
Loading…
Add table
Reference in a new issue