Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 25 additions & 28 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,23 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<java.version>17</java.version>
<start-class>murraco.JwtAuthServiceApp</start-class>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<version>3.4.4</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>

<dependencies>
<dependency>
<!-- Setup Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<!-- JPA Data (Repositories, Entities, Hibernate, etc..) -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Expand All @@ -40,32 +38,30 @@
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<!-- Starter for using Spring Security -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<!-- Make method based security testing easier -->
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<!-- Automatically restart whenever files on the classpath change -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- Add MySQL Connector dependency -->
<dependency>
<!-- Use MySQL Connector-J -->
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.2.0</version><!-- A compatible version with Spring Boot 3 and MySQL 8 -->
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
Expand All @@ -74,29 +70,30 @@
<scope>provided</scope>
</dependency>
<dependency>
<!-- Automated JSON API documentation for API's built with Spring -->
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<!-- Generate beautiful documentation from a Swagger-compliant API. -->
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.10.0</version>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<!-- JSON Web Token Support -->
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<!-- Model Mapper -->
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.4.4</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>

<build>
Expand All @@ -108,4 +105,4 @@
</plugins>
</build>

</project>
</project>
13 changes: 6 additions & 7 deletions src/main/java/murraco/JwtAuthServiceApp.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package murraco;

import java.util.ArrayList;
import java.util.Arrays;

import lombok.RequiredArgsConstructor;
import murraco.model.AppUser;
import murraco.model.AppUserRole;
import murraco.service.UserService;
import org.modelmapper.ModelMapper;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import murraco.service.UserService;
import java.util.ArrayList;
import java.util.List;

@SpringBootApplication
@RequiredArgsConstructor
Expand All @@ -30,20 +29,20 @@ public ModelMapper modelMapper() {
}

@Override
public void run(String... params) throws Exception {
public void run(String... params) {
AppUser admin = new AppUser();
admin.setUsername("admin");
admin.setPassword("admin");
admin.setEmail("[email protected]");
admin.setAppUserRoles(new ArrayList<AppUserRole>(Arrays.asList(AppUserRole.ROLE_ADMIN)));
admin.setAppUserRoles(new ArrayList<>(List.of(AppUserRole.ROLE_ADMIN)));

userService.signup(admin);

AppUser client = new AppUser();
client.setUsername("client");
client.setPassword("client");
client.setEmail("[email protected]");
client.setAppUserRoles(new ArrayList<AppUserRole>(Arrays.asList(AppUserRole.ROLE_CLIENT)));
client.setAppUserRoles(new ArrayList<>(List.of(AppUserRole.ROLE_CLIENT)));

userService.signup(client);
}
Expand Down
75 changes: 0 additions & 75 deletions src/main/java/murraco/configuration/SwaggerConfig.java

This file was deleted.

83 changes: 43 additions & 40 deletions src/main/java/murraco/controller/UserController.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package murraco.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;

import lombok.RequiredArgsConstructor;
import murraco.model.AppUser;
Expand All @@ -15,78 +21,75 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
import murraco.dto.UserDataDTO;
import murraco.dto.UserResponseDTO;
import murraco.service.UserService;

@RestController
@RequestMapping("/users")
@Api(tags = "users")
@Tag(name = "users")
@RequiredArgsConstructor
public class UserController {

private final UserService userService;
private final ModelMapper modelMapper;

@PostMapping("/signin")
@ApiOperation(value = "${UserController.signin}")
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 422, message = "Invalid username/password supplied")})
public String login(//
@ApiParam("Username") @RequestParam String username, //
@ApiParam("Password") @RequestParam String password) {
@Operation(summary = "${UserController.signin}")
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Something went wrong"),
@ApiResponse(responseCode = "422", description = "Invalid username/password supplied")
})
public String login(
@Parameter(description = "Username") @RequestParam String username,
@Parameter(description = "Password") @RequestParam String password) {
return userService.signin(username, password);
}

@PostMapping("/signup")
@ApiOperation(value = "${UserController.signup}")
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 422, message = "Username is already in use")})
public String signup(@ApiParam("Signup User") @RequestBody UserDataDTO user) {
@Operation(summary = "${UserController.signup}")
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Something went wrong"),
@ApiResponse(responseCode = "403", description = "Access denied"),
@ApiResponse(responseCode = "422", description = "Username is already in use")
})
public String signup(@Parameter(description = "Signup User") @RequestBody UserDataDTO user) {
return userService.signup(modelMapper.map(user, AppUser.class));
}

@DeleteMapping(value = "/{username}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@ApiOperation(value = "${UserController.delete}", authorizations = { @Authorization(value="apiKey") })
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 404, message = "The user doesn't exist"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")})
public String delete(@ApiParam("Username") @PathVariable String username) {
@Operation(summary = "${UserController.delete}", security = @SecurityRequirement(name = "apiKey"))
@ApiResponses(value = {
@ApiResponse(responseCode = "400", description = "Something went wrong"),
@ApiResponse(responseCode = "403", description = "Access denied"),
@ApiResponse(responseCode = "404", description = "The user doesn't exist"),
@ApiResponse(responseCode = "500", description = "Expired or invalid JWT token")
})
public String delete(@Parameter(description = "Username") @PathVariable String username) {
userService.delete(username);
return username;
}

@GetMapping(value = "/{username}")
@PreAuthorize("hasRole('ROLE_ADMIN')")
@ApiOperation(value = "${UserController.search}", response = UserResponseDTO.class, authorizations = { @Authorization(value="apiKey") })
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 404, message = "The user doesn't exist"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")})
public UserResponseDTO search(@ApiParam("Username") @PathVariable String username) {
@Operation(summary = "${UserController.search}", responses = {
@ApiResponse(responseCode = "400", description = "Something went wrong"),
@ApiResponse(responseCode = "403", description = "Access denied"),
@ApiResponse(responseCode = "404", description = "The user doesn't exist"),
@ApiResponse(responseCode = "500", description = "Expired or invalid JWT token")
}, security = @SecurityRequirement(name = "apiKey"))
public UserResponseDTO search(@Parameter(description = "Username") @PathVariable String username) {
return modelMapper.map(userService.search(username), UserResponseDTO.class);
}

@GetMapping(value = "/me")
@PreAuthorize("hasRole('ROLE_ADMIN') or hasRole('ROLE_CLIENT')")
@ApiOperation(value = "${UserController.me}", response = UserResponseDTO.class, authorizations = { @Authorization(value="apiKey") })
@ApiResponses(value = {//
@ApiResponse(code = 400, message = "Something went wrong"), //
@ApiResponse(code = 403, message = "Access denied"), //
@ApiResponse(code = 500, message = "Expired or invalid JWT token")})
@Operation(summary = "${UserController.me}", responses = {
@ApiResponse(responseCode = "400", description = "Something went wrong"),
@ApiResponse(responseCode = "403", description = "Access denied"),
@ApiResponse(responseCode = "500", description = "Expired or invalid JWT token")
}, security = @SecurityRequirement(name = "apiKey"))
public UserResponseDTO whoami(HttpServletRequest req) {
return modelMapper.map(userService.whoami(req), UserResponseDTO.class);
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/murraco/dto/UserDataDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

import java.util.List;

import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import murraco.model.AppUserRole;

@Data
@NoArgsConstructor
public class UserDataDTO {
@ApiModelProperty(position = 0)

@Schema(description = "Username")
private String username;
@ApiModelProperty(position = 1)
@Schema(description = "Email")
private String email;
@ApiModelProperty(position = 2)
@Schema(description = "Password")
private String password;
@ApiModelProperty(position = 3)
@Schema(description = "User roles")
List<AppUserRole> appUserRoles;

}
Loading