Merge pull request 'database' (#2) from database into master
Reviewed-on: #2
This commit is contained in:
commit
24152ec239
12
pom.xml
12
pom.xml
@ -48,6 +48,18 @@
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-smallrye-jwt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-postgresql</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-hibernate-orm-panache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-security-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
|
@ -0,0 +1,47 @@
|
||||
package com.covas.ApplicationScoped;
|
||||
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import io.quarkus.runtime.ShutdownEvent;
|
||||
import io.quarkus.runtime.StartupEvent;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
|
||||
import javax.enterprise.context.ApplicationScoped;
|
||||
import javax.enterprise.event.Observes;
|
||||
import javax.inject.Inject;
|
||||
import javax.transaction.Transactional;
|
||||
|
||||
import com.covas.Entity.UsersEntity;
|
||||
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
|
||||
|
||||
@ApplicationScoped
|
||||
public class ApplicationLifeCycle {
|
||||
@Inject
|
||||
@ConfigProperty(name = "covas.schema.create", defaultValue = "true")
|
||||
boolean schemaCreate;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ApplicationLifeCycle.class);
|
||||
|
||||
@Transactional
|
||||
void onStart(@Observes StartupEvent ev) {
|
||||
LOGGER.info("The application has started");
|
||||
if (schemaCreate){
|
||||
UsersEntity.deleteAll();
|
||||
LOGGER.info("Robert80 user is created");
|
||||
UsersEntity.add("robert80", "robert80@gmail.com", "titi", "robert", LocalDate.of(1990, Month.JANUARY, 23), "toto", "User");
|
||||
LOGGER.info("Peter93 user is created");
|
||||
UsersEntity.add("peter93", "peter93gmail.com", "yollo", "peter", LocalDate.of(1993, Month.FEBRUARY, 26), "toto", "Admin");
|
||||
} else {
|
||||
LOGGER.info("DB init wassn't created");
|
||||
}
|
||||
}
|
||||
void onStop(@Observes ShutdownEvent ev) {
|
||||
LOGGER.info("The application is stopping...");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.covas.ApplicationScoped;
|
||||
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.core.Application;
|
||||
|
||||
@ApplicationPath("/api")
|
||||
public class ApplicationRoot extends Application {
|
||||
|
||||
}
|
42
src/main/java/com/covas/Classes/Hash.java
Normal file
42
src/main/java/com/covas/Classes/Hash.java
Normal file
@ -0,0 +1,42 @@
|
||||
package com.covas.Classes;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class Hash {
|
||||
|
||||
|
||||
public static String encryptSHA512(String input)
|
||||
{
|
||||
try {
|
||||
// getInstance() method is called with algorithm SHA-512
|
||||
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||
|
||||
// digest() method is called
|
||||
// to calculate message digest of the input string
|
||||
// returned as array of byte
|
||||
byte[] messageDigest = md.digest(input.getBytes());
|
||||
|
||||
// Convert byte array into signum representation
|
||||
BigInteger no = new BigInteger(1, messageDigest);
|
||||
|
||||
// Convert message digest into hex value
|
||||
String hashtext = no.toString(16);
|
||||
|
||||
// Add preceding 0s to make it 32 bit
|
||||
while (hashtext.length() < 32) {
|
||||
hashtext = "0" + hashtext;
|
||||
}
|
||||
|
||||
// return the HashText
|
||||
return hashtext;
|
||||
}
|
||||
|
||||
// For specifying wrong message digest algorithms
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
64
src/main/java/com/covas/Entity/UsersEntity.java
Normal file
64
src/main/java/com/covas/Entity/UsersEntity.java
Normal file
@ -0,0 +1,64 @@
|
||||
package com.covas.Entity;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Generated;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import com.covas.Classes.Hash;
|
||||
|
||||
import org.hibernate.annotations.ColumnDefault;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
|
||||
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class UsersEntity extends PanacheEntityBase {
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@GeneratedValue(generator = "UUID")
|
||||
@GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
|
||||
public UUID id;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
public String pseudo;
|
||||
@Column(nullable = false, unique = true)
|
||||
public String email;
|
||||
@Column(nullable = false)
|
||||
public String name;
|
||||
@Column(nullable = false)
|
||||
public String firstName;
|
||||
@Column(nullable = false)
|
||||
public LocalDate birth;
|
||||
@ColumnDefault("false")
|
||||
public Boolean status;
|
||||
@Column(nullable = false)
|
||||
public String password;
|
||||
public String roles;
|
||||
|
||||
public static UsersEntity findByPseudo(String pseudo){
|
||||
return find("pseudo", pseudo).firstResult();
|
||||
}
|
||||
|
||||
public static void add(String pseudo, String email, String name, String firstName, LocalDate birth, String password, String roles){
|
||||
|
||||
UsersEntity users = new UsersEntity();
|
||||
users.pseudo = pseudo;
|
||||
users.email = email;
|
||||
users.name = name;
|
||||
users.firstName = firstName;
|
||||
users.birth = birth;
|
||||
users.status = false;
|
||||
users.password = Hash.encryptSHA512(password);
|
||||
users.roles = roles;
|
||||
users.persist();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.covas;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/json")
|
||||
public class HelloRessource {
|
||||
Set<Hello> hello = Collections.synchronizedSet(new LinkedHashSet<>());
|
||||
|
||||
public HelloRessource(){
|
||||
hello.add(new Hello("toto"));
|
||||
}
|
||||
|
||||
@GET
|
||||
public Response hello_json(){
|
||||
return Response.ok(this.hello).build();
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.covas;
|
||||
package com.covas.Json;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
@ -1,36 +0,0 @@
|
||||
package com.covas;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
public class Jwt2 {
|
||||
|
||||
public String name;
|
||||
public Boolean status;
|
||||
public String message;
|
||||
|
||||
public Jwt2(){
|
||||
name = "";
|
||||
status = true;
|
||||
message = "";
|
||||
}
|
||||
|
||||
public Jwt2(String name){
|
||||
this.name = name;
|
||||
status = true;
|
||||
message = "";
|
||||
}
|
||||
|
||||
public Jwt2(String name, String message){
|
||||
this.name = name;
|
||||
this.message = message;
|
||||
status = true;
|
||||
}
|
||||
|
||||
public Jwt2(String name, Boolean status, String message){
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.covas;
|
||||
package com.covas.Resources;
|
||||
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
56
src/main/java/com/covas/Resources/HelloRessource.java
Normal file
56
src/main/java/com/covas/Resources/HelloRessource.java
Normal file
@ -0,0 +1,56 @@
|
||||
package com.covas.Resources;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import com.covas.Json.Hello;
|
||||
|
||||
import org.eclipse.microprofile.jwt.JsonWebToken;
|
||||
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/json")
|
||||
public class HelloRessource {
|
||||
@Inject
|
||||
JsonWebToken jwt;
|
||||
|
||||
Set<Hello> hello = Collections.synchronizedSet(new LinkedHashSet<>());
|
||||
|
||||
public HelloRessource(){
|
||||
hello.add(new Hello("toto"));
|
||||
}
|
||||
|
||||
@GET
|
||||
@PermitAll
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response hello_json(){
|
||||
return Response.ok(this.hello).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/user")
|
||||
@RolesAllowed({"User"})
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response hello_user(){
|
||||
return Response.ok(new Hello(String.format("Hello %s", jwt.getName()))).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/admin")
|
||||
@RolesAllowed({"Admin"})
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response hello_admin(){
|
||||
return Response.ok(new Hello(String.format("Hello admin %s", jwt.getName()))).build();
|
||||
}
|
||||
}
|
77
src/main/java/com/covas/Resources/TokenRessource.java
Normal file
77
src/main/java/com/covas/Resources/TokenRessource.java
Normal file
@ -0,0 +1,77 @@
|
||||
package com.covas.Resources;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.CookieParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.NewCookie;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import com.covas.Classes.Hash;
|
||||
import com.covas.Entity.UsersEntity;
|
||||
|
||||
import io.smallrye.jwt.auth.principal.JWTParser;
|
||||
import io.smallrye.jwt.auth.principal.ParseException;
|
||||
import io.smallrye.jwt.build.Jwt;
|
||||
|
||||
import org.eclipse.microprofile.jwt.JsonWebToken;
|
||||
import org.jboss.resteasy.annotations.jaxrs.HeaderParam;
|
||||
import org.postgresql.shaded.com.ongres.scram.common.bouncycastle.base64.Base64;
|
||||
|
||||
@Path("/api")
|
||||
public class TokenRessource {
|
||||
@Inject
|
||||
JsonWebToken jwt;
|
||||
|
||||
|
||||
@Inject JWTParser parser;
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("token")
|
||||
public Response getUserName(@HeaderParam("Authorization") String auth, @CookieParam("jwt") String jwtCookie) {
|
||||
String name = "anonymous";
|
||||
String password = "";
|
||||
|
||||
if (jwtCookie == null) {
|
||||
String[] hash = new String(Base64.decode(auth.split(" ")[1]), StandardCharsets.UTF_8).split(":");
|
||||
name = hash[0];
|
||||
password = Hash.encryptSHA512(hash[1]);
|
||||
|
||||
UsersEntity users = UsersEntity.findByPseudo(name);
|
||||
if(users != null){
|
||||
|
||||
if(password.equals(users.password)){
|
||||
// Create a JWT token signed using the 'HS256' algorithm
|
||||
String newJwtCookie = Jwt.issuer("https://example.com/issuer").upn(name).groups(new HashSet<>(Arrays.asList(users.roles))).sign();
|
||||
// or create a JWT token encrypted using the 'A256KW' algorithm
|
||||
// Jwt.upn("alice").encryptWithSecret(secret);
|
||||
return Response.status(Response.Status.CREATED).cookie(new NewCookie("jwt", newJwtCookie)).build();
|
||||
} else {
|
||||
return Response.status(Response.Status.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
|
||||
} else {
|
||||
// All mp.jwt and smallrye.jwt properties are still effective, only the verification key is customized.
|
||||
try {
|
||||
jwt = parser.parse(jwtCookie);
|
||||
}
|
||||
catch(ParseException p){
|
||||
return Response.status(Response.Status.UNAUTHORIZED).build();
|
||||
}
|
||||
// or jwt = parser.decrypt(jwtCookie, secret);
|
||||
return Response.status(Response.Status.OK).build();
|
||||
}
|
||||
}
|
||||
}
|
48
src/main/java/com/covas/Resources/UsersRessources.java
Normal file
48
src/main/java/com/covas/Resources/UsersRessources.java
Normal file
@ -0,0 +1,48 @@
|
||||
package com.covas.Resources;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import com.covas.Entity.UsersEntity;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("users")
|
||||
public class UsersRessources {
|
||||
private static final Logger LOGGER = Logger.getLogger(UsersRessources.class);
|
||||
@GET
|
||||
@RolesAllowed({"Admin"})
|
||||
public Response getUsers(){
|
||||
return Response.ok(UsersEntity.listAll()).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@RolesAllowed({"Admin"})
|
||||
@Path("{id}")
|
||||
public Response getSingleUser(@PathParam("id") String id){
|
||||
UUID uid = UUID.fromString(id);
|
||||
UsersEntity users = UsersEntity.findById(uid);
|
||||
if(users == null){
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
return Response.ok(users).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@RolesAllowed({"User"})
|
||||
@Path("info")
|
||||
public Response getInfoUser(){
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.covas;
|
||||
|
||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||
|
||||
@RegisterForReflection
|
||||
public class Token {
|
||||
|
||||
public String name;
|
||||
public Boolean isHttps;
|
||||
public String authScheme;
|
||||
public Boolean hasJwt;
|
||||
public String birthday;
|
||||
public String role = "";
|
||||
|
||||
public Token(){
|
||||
this.name = "anonymous";
|
||||
this.isHttps = false;
|
||||
this.authScheme = "";
|
||||
this.hasJwt = false;
|
||||
this.birthday = "";
|
||||
this.role = "";
|
||||
}
|
||||
|
||||
public Token(String name, Boolean isHttps, String authScheme, Boolean hasJwt){
|
||||
this.name = name;
|
||||
this.isHttps = isHttps;
|
||||
this.authScheme = authScheme;
|
||||
this.hasJwt = hasJwt;
|
||||
this.birthday = "";
|
||||
this.role = "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
package com.covas;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.CookieParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.InternalServerErrorException;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.NewCookie;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.SecurityContext;
|
||||
|
||||
import io.smallrye.jwt.auth.principal.JWTParser;
|
||||
import io.smallrye.jwt.auth.principal.ParseException;
|
||||
import io.smallrye.jwt.build.Jwt;
|
||||
|
||||
import org.eclipse.microprofile.jwt.JsonWebToken;
|
||||
|
||||
|
||||
@Path("/token")
|
||||
public class TokenRessource {
|
||||
|
||||
|
||||
@Inject
|
||||
JsonWebToken jwt;
|
||||
|
||||
@Inject JWTParser parser;
|
||||
|
||||
|
||||
@GET
|
||||
@Path("authentificate")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response getUserName(@CookieParam("jwt") String jwtCookie) {
|
||||
if (jwtCookie == null) {
|
||||
// Create a JWT token signed using the 'HS256' algorithm
|
||||
String newJwtCookie = Jwt.issuer("https://example.com/issuer").upn("Alice").groups(new HashSet<>(Arrays.asList("User"))).sign();
|
||||
// or create a JWT token encrypted using the 'A256KW' algorithm
|
||||
// Jwt.upn("alice").encryptWithSecret(secret);
|
||||
|
||||
return Response.status(Response.Status.CREATED).entity(new Jwt2("Alice")).cookie(new NewCookie("jwt", newJwtCookie)).build();
|
||||
} else {
|
||||
// All mp.jwt and smallrye.jwt properties are still effective, only the verification key is customized.
|
||||
try {
|
||||
jwt = parser.parse(jwtCookie);
|
||||
}
|
||||
catch(ParseException p){
|
||||
return Response.status(Response.Status.NOT_ACCEPTABLE).entity(new Jwt2("Alice", false, p.getMessage())).build();
|
||||
}
|
||||
// or jwt = parser.decrypt(jwtCookie, secret);
|
||||
return Response.status(Response.Status.OK).entity(new Jwt2(jwt.getName())).build();
|
||||
}
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("permit-all")
|
||||
@PermitAll
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Token hello(@Context SecurityContext ctx) {
|
||||
return getResponseString(ctx);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("roles-allowed")
|
||||
@RolesAllowed({"Admin" })
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Token helloRolesAllowed(@Context SecurityContext ctx) {
|
||||
Token token = getResponseString(ctx);
|
||||
token.name = jwt.getName().toString();
|
||||
token.role = "Admin";
|
||||
return token;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("roles-user")
|
||||
@RolesAllowed({"Toto"})
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Token helloRolesUser(@Context SecurityContext ctx) {
|
||||
Token token = getResponseString(ctx);
|
||||
token.name = jwt.getName().toString();
|
||||
token.role = "User";
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
private Token getResponseString(SecurityContext ctx) {
|
||||
String name;
|
||||
if (ctx.getUserPrincipal() == null) {
|
||||
name = "anonymous";
|
||||
} else if (!ctx.getUserPrincipal().getName().equals(jwt.getName())) {
|
||||
throw new InternalServerErrorException("Principal and JsonWebToken names do not match");
|
||||
} else {
|
||||
name = ctx.getUserPrincipal().getName();
|
||||
}
|
||||
return new Token(name, ctx.isSecure(), ctx.getAuthenticationScheme(), hasJwt());
|
||||
}
|
||||
|
||||
private boolean hasJwt() {
|
||||
return jwt.getClaimNames() != null;
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -1,6 +1,14 @@
|
||||
smallrye.jwt.sign.key.location=privateKey.pem
|
||||
|
||||
|
||||
|
||||
mp.jwt.verify.publickey.location=publicKey.pem
|
||||
mp.jwt.verify.issuer=https://example.com/issuer
|
||||
|
||||
quarkus.datasource.db-kind = postgresql
|
||||
quarkus.datasource.username = toto
|
||||
quarkus.datasource.password = toto
|
||||
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/toto
|
||||
# drop and create the database at startup (use `update` to only update the schema)
|
||||
quarkus.hibernate-orm.database.generation = drop-and-create
|
||||
|
||||
covas.schema.create = true
|
@ -12,7 +12,7 @@ public class GreetingResourceTest {
|
||||
@Test
|
||||
public void testHelloEndpoint() {
|
||||
given()
|
||||
.when().get("/hello")
|
||||
.when().get("/api/hello")
|
||||
.then()
|
||||
.statusCode(200)
|
||||
.body(is("Hello RESTEasy"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user