Co-authored-by: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com> Reviewed-on: #48
This commit was merged in pull request #48.
This commit is contained in:
Vendored
+2
-1
@@ -7,7 +7,8 @@
|
|||||||
"**/Thumbs.db": true,
|
"**/Thumbs.db": true,
|
||||||
"**/target": true,
|
"**/target": true,
|
||||||
"**/docker": true,
|
"**/docker": true,
|
||||||
"node_modules": true
|
"node_modules": true,
|
||||||
|
"**/.mvn": true
|
||||||
},
|
},
|
||||||
"explorerExclude.backup": {},
|
"explorerExclude.backup": {},
|
||||||
"java.compile.nullAnalysis.mode": "automatic",
|
"java.compile.nullAnalysis.mode": "automatic",
|
||||||
|
|||||||
@@ -54,6 +54,12 @@
|
|||||||
<artifactId>jose4j</artifactId>
|
<artifactId>jose4j</artifactId>
|
||||||
<version>0.9.3</version>
|
<version>0.9.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.datafaker</groupId>
|
||||||
|
<artifactId>datafaker</artifactId>
|
||||||
|
<version>2.0.2</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.quarkus</groupId>
|
<groupId>io.quarkus</groupId>
|
||||||
<artifactId>quarkus-messaging-kafka</artifactId>
|
<artifactId>quarkus-messaging-kafka</artifactId>
|
||||||
|
|||||||
@@ -3,11 +3,20 @@ package com.drinkool.entities;
|
|||||||
import com.drinkool.Role;
|
import com.drinkool.Role;
|
||||||
import com.drinkool.models.UserModel;
|
import com.drinkool.models.UserModel;
|
||||||
import jakarta.persistence.*;
|
import jakarta.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = Role.Manager)
|
@Table(name = Role.Manager)
|
||||||
public class ManagerEntity extends UserModel {
|
public class ManagerEntity extends UserModel {
|
||||||
|
|
||||||
|
@OneToMany(
|
||||||
|
mappedBy = "serve",
|
||||||
|
cascade = CascadeType.ALL,
|
||||||
|
orphanRemoval = true
|
||||||
|
)
|
||||||
|
public List<StaffEntity> staffs = new ArrayList<>();
|
||||||
|
|
||||||
public ManagerEntity() {
|
public ManagerEntity() {
|
||||||
super(Role.Manager);
|
super(Role.Manager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.drinkool.entities;
|
||||||
|
|
||||||
|
import com.drinkool.Role;
|
||||||
|
import com.drinkool.models.UserModel;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.FetchType;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = Role.Staff)
|
||||||
|
public class StaffEntity extends UserModel {
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void signup(
|
||||||
|
String name,
|
||||||
|
String phone,
|
||||||
|
String rawPassword,
|
||||||
|
ManagerEntity serve
|
||||||
|
) {
|
||||||
|
this.serve = serve;
|
||||||
|
super.signup(name, phone, rawPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "managerId")
|
||||||
|
public ManagerEntity serve;
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.drinkool.filters;
|
||||||
|
|
||||||
|
import com.drinkool.lib.utils.BaseHeaderAuthentication;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class HeaderRolesFilter extends BaseHeaderAuthentication {}
|
||||||
@@ -3,6 +3,7 @@ package com.drinkool.services;
|
|||||||
import com.drinkool.Role;
|
import com.drinkool.Role;
|
||||||
import com.drinkool.Url;
|
import com.drinkool.Url;
|
||||||
import com.drinkool.entities.ManagerEntity;
|
import com.drinkool.entities.ManagerEntity;
|
||||||
|
import com.drinkool.entities.StaffEntity;
|
||||||
import com.drinkool.lib.dtos.SmsOtp;
|
import com.drinkool.lib.dtos.SmsOtp;
|
||||||
import com.drinkool.models.UserModel;
|
import com.drinkool.models.UserModel;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
@@ -28,6 +29,10 @@ public class AccountService {
|
|||||||
ManagerEntity.find("phone", input.phone).firstResult() != null
|
ManagerEntity.find("phone", input.phone).firstResult() != null
|
||||||
) return Response.accepted().entity(Role.Manager).build();
|
) return Response.accepted().entity(Role.Manager).build();
|
||||||
|
|
||||||
|
if (
|
||||||
|
StaffEntity.find("phone", input.phone).firstResult() != null
|
||||||
|
) return Response.accepted().entity(Role.Staff).build();
|
||||||
|
|
||||||
String otp = otpService.generateAndSaveOtp(input.phone);
|
String otp = otpService.generateAndSaveOtp(input.phone);
|
||||||
|
|
||||||
System.out.println("OTP cho " + input.phone + " là: " + otp);
|
System.out.println("OTP cho " + input.phone + " là: " + otp);
|
||||||
|
|||||||
@@ -44,25 +44,25 @@ public class ManagerService extends BaseService<ManagerEntity> {
|
|||||||
@POST
|
@POST
|
||||||
@Path(Url.Login)
|
@Path(Url.Login)
|
||||||
public Response login(Login input) {
|
public Response login(Login input) {
|
||||||
ManagerEntity customer = ManagerEntity.find(
|
ManagerEntity manager = ManagerEntity.find(
|
||||||
"phone",
|
"phone",
|
||||||
input.phone
|
input.phone
|
||||||
).firstResult();
|
).firstResult();
|
||||||
|
|
||||||
if (customer == null) return Response.status(Response.Status.BAD_REQUEST)
|
if (manager == null) return Response.status(Response.Status.BAD_REQUEST)
|
||||||
.entity("InvalidPhoneNumber")
|
.entity("InvalidPhoneNumber")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
if (!customer.login(input.password)) return Response.status(
|
if (!manager.login(input.password)) return Response.status(
|
||||||
Response.Status.BAD_REQUEST
|
Response.Status.BAD_REQUEST
|
||||||
)
|
)
|
||||||
.entity("InvalidPassword")
|
.entity("InvalidPassword")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return Response.accepted()
|
return Response.accepted()
|
||||||
.header(InternalValue.userId, customer.id.toString())
|
.header(InternalValue.userId, manager.id.toString())
|
||||||
.header(InternalValue.role, Role.Manager)
|
.header(InternalValue.role, Role.Manager)
|
||||||
.entity(customer)
|
.entity(manager)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package com.drinkool.services;
|
||||||
|
|
||||||
|
import com.drinkool.InternalValue;
|
||||||
|
import com.drinkool.Role;
|
||||||
|
import com.drinkool.Url;
|
||||||
|
import com.drinkool.entities.ManagerEntity;
|
||||||
|
import com.drinkool.entities.StaffEntity;
|
||||||
|
import com.drinkool.lib.dtos.Login;
|
||||||
|
import com.drinkool.lib.dtos.Signup;
|
||||||
|
import io.vertx.core.http.HttpServerRequest;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import jakarta.ws.rs.POST;
|
||||||
|
import jakarta.ws.rs.Path;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Path(Role.Staff)
|
||||||
|
public class StaffService extends BaseService<StaffEntity> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
HttpServerRequest request;
|
||||||
|
|
||||||
|
public StaffService() {
|
||||||
|
super(StaffEntity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path(Url.Signup)
|
||||||
|
@RolesAllowed(Role.Manager)
|
||||||
|
@Transactional
|
||||||
|
public Response signup(Signup input) {
|
||||||
|
UUID managerId = UUID.fromString(request.getHeader(InternalValue.userId));
|
||||||
|
ManagerEntity manager = ManagerEntity.findById(managerId);
|
||||||
|
|
||||||
|
if (manager == null) return Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
.entity("InvalidManager")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
StaffEntity staff = new StaffEntity();
|
||||||
|
staff.signup(input.name, input.phone, input.password, manager);
|
||||||
|
|
||||||
|
return Response.status(Response.Status.CREATED)
|
||||||
|
.header(InternalValue.userId, staff.id.toString())
|
||||||
|
.header(InternalValue.role, Role.Staff)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path(Url.Login)
|
||||||
|
public Response login(Login input) {
|
||||||
|
StaffEntity staff = StaffEntity.find("phone", input.phone).firstResult();
|
||||||
|
|
||||||
|
if (staff == null) return Response.status(Response.Status.BAD_REQUEST)
|
||||||
|
.entity("InvalidPhoneNumber")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
if (!staff.login(input.password)) return Response.status(
|
||||||
|
Response.Status.BAD_REQUEST
|
||||||
|
)
|
||||||
|
.entity("InvalidPassword")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return Response.accepted()
|
||||||
|
.header(InternalValue.userId, staff.id.toString())
|
||||||
|
.header(InternalValue.role, Role.Staff)
|
||||||
|
.entity(staff)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package com.drinkool.services;
|
||||||
|
|
||||||
|
import static io.restassured.RestAssured.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
import com.drinkool.*;
|
||||||
|
import com.drinkool.entities.StaffEntity;
|
||||||
|
import com.drinkool.lib.dtos.*;
|
||||||
|
import io.quarkus.test.common.QuarkusTestResource;
|
||||||
|
import io.quarkus.test.junit.QuarkusTest;
|
||||||
|
import io.quarkus.test.kafka.*;
|
||||||
|
import io.restassured.http.ContentType;
|
||||||
|
import io.smallrye.reactive.messaging.kafka.companion.ConsumerTask;
|
||||||
|
import io.smallrye.reactive.messaging.kafka.companion.KafkaCompanion;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import java.time.Duration;
|
||||||
|
import net.datafaker.Faker;
|
||||||
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
@QuarkusTest
|
||||||
|
@QuarkusTestResource(KafkaCompanionResource.class)
|
||||||
|
public class StaffServiceTest {
|
||||||
|
|
||||||
|
private final Faker faker = new Faker();
|
||||||
|
|
||||||
|
private String managerId;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
ManagerSignup input = new ManagerSignup();
|
||||||
|
input.name = "Ho Van Quan";
|
||||||
|
input.phone = Utils.generateRandomPhone();
|
||||||
|
input.password = "strong_password";
|
||||||
|
input.eateryName = "Quan Com Ngon";
|
||||||
|
|
||||||
|
var response = given()
|
||||||
|
.contentType("application/json")
|
||||||
|
.body(input)
|
||||||
|
.when()
|
||||||
|
.post(Role.Manager + Url.Signup)
|
||||||
|
.then()
|
||||||
|
.statusCode(201)
|
||||||
|
.header(InternalValue.userId, org.hamcrest.Matchers.notNullValue())
|
||||||
|
.header(InternalValue.role, Role.Manager)
|
||||||
|
.extract();
|
||||||
|
|
||||||
|
managerId = response.header(InternalValue.userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void signup_Success() {
|
||||||
|
String staffName = faker.name().fullName();
|
||||||
|
String staffPhone = Utils.generateRandomPhone();
|
||||||
|
|
||||||
|
Signup signup = new Signup(
|
||||||
|
staffName,
|
||||||
|
staffPhone,
|
||||||
|
faker.famousLastWords().lastWords()
|
||||||
|
);
|
||||||
|
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.header(InternalValue.role, Role.Manager)
|
||||||
|
.header(InternalValue.userId, managerId)
|
||||||
|
.body(signup)
|
||||||
|
.when()
|
||||||
|
.post(Role.Staff + Url.Signup)
|
||||||
|
.then()
|
||||||
|
.statusCode(Response.Status.CREATED.getStatusCode())
|
||||||
|
.header(InternalValue.userId, org.hamcrest.Matchers.notNullValue())
|
||||||
|
.header(InternalValue.role, Role.Staff);
|
||||||
|
|
||||||
|
StaffEntity staff = StaffEntity.find("phone", staffPhone).firstResult();
|
||||||
|
|
||||||
|
assertEquals(managerId, staff.serve.id.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void signup_FailedDueToInvalidRole() {
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.header(InternalValue.role, Role.Customer)
|
||||||
|
.header(InternalValue.userId, managerId)
|
||||||
|
.body("")
|
||||||
|
.when()
|
||||||
|
.post(Role.Staff + Url.Signup)
|
||||||
|
.then()
|
||||||
|
.statusCode(Response.Status.FORBIDDEN.getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLoginSuccess() {
|
||||||
|
String staffName = faker.name().fullName();
|
||||||
|
String staffPhone = Utils.generateRandomPhone();
|
||||||
|
String password = faker.famousLastWords().lastWords();
|
||||||
|
|
||||||
|
Signup signup = new Signup(staffName, staffPhone, password);
|
||||||
|
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.header(InternalValue.role, Role.Manager)
|
||||||
|
.header(InternalValue.userId, managerId)
|
||||||
|
.body(signup)
|
||||||
|
.when()
|
||||||
|
.post(Role.Staff + Url.Signup)
|
||||||
|
.then();
|
||||||
|
|
||||||
|
Login loginInput = new Login(staffPhone, password);
|
||||||
|
|
||||||
|
given()
|
||||||
|
.contentType(ContentType.JSON)
|
||||||
|
.body(loginInput)
|
||||||
|
.when()
|
||||||
|
.post(Role.Staff + Url.Login)
|
||||||
|
.then()
|
||||||
|
.statusCode(Response.Status.ACCEPTED.getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -181,6 +181,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
|
<quarkus.package.jar.enabled>false</quarkus.package.jar.enabled>
|
||||||
<skipITs>false</skipITs>
|
<skipITs>false</skipITs>
|
||||||
<quarkus.native.enabled>true</quarkus.native.enabled>
|
<quarkus.native.enabled>true</quarkus.native.enabled>
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.drinkool.controller;
|
package com.drinkool.controller;
|
||||||
|
|
||||||
|
import com.drinkool.InternalValue;
|
||||||
import com.drinkool.Url;
|
import com.drinkool.Url;
|
||||||
import com.drinkool.enums.SortBy;
|
import com.drinkool.enums.SortBy;
|
||||||
import com.drinkool.lib.dtos.GraphqlDto;
|
import com.drinkool.lib.dtos.GraphqlDto;
|
||||||
@@ -9,6 +10,7 @@ import io.smallrye.mutiny.Uni;
|
|||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.DefaultValue;
|
import jakarta.ws.rs.DefaultValue;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.HeaderParam;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
@@ -43,8 +45,12 @@ public class EateryController extends GraphqlBase {
|
|||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path(Url.Review)
|
@Path(Url.Review)
|
||||||
public Uni<Response> receiveReview(SendReview input) {
|
public Uni<Response> receiveReview(
|
||||||
return reviewService.receiveReview(input);
|
SendReview input,
|
||||||
|
@HeaderParam(InternalValue.userId) UUID userId,
|
||||||
|
@HeaderParam(InternalValue.role) String role
|
||||||
|
) {
|
||||||
|
return reviewService.receiveReview(input, userId, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package com.drinkool.services;
|
package com.drinkool.services;
|
||||||
|
|
||||||
|
import com.drinkool.InternalValue;
|
||||||
import com.drinkool.Url;
|
import com.drinkool.Url;
|
||||||
import com.drinkool.enums.SortBy;
|
import com.drinkool.enums.SortBy;
|
||||||
import com.drinkool.lib.dtos.SendReview;
|
import com.drinkool.lib.dtos.SendReview;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import jakarta.ws.rs.DefaultValue;
|
import jakarta.ws.rs.DefaultValue;
|
||||||
import jakarta.ws.rs.GET;
|
import jakarta.ws.rs.GET;
|
||||||
|
import jakarta.ws.rs.HeaderParam;
|
||||||
import jakarta.ws.rs.POST;
|
import jakarta.ws.rs.POST;
|
||||||
import jakarta.ws.rs.Path;
|
import jakarta.ws.rs.Path;
|
||||||
import jakarta.ws.rs.PathParam;
|
import jakarta.ws.rs.PathParam;
|
||||||
@@ -25,5 +27,9 @@ public interface ReviewService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
public Uni<Response> receiveReview(SendReview input);
|
public Uni<Response> receiveReview(
|
||||||
|
SendReview input,
|
||||||
|
@HeaderParam(InternalValue.userId) UUID userId,
|
||||||
|
@HeaderParam(InternalValue.role) String role
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ public class Role {
|
|||||||
|
|
||||||
public static final String Customer = "customer";
|
public static final String Customer = "customer";
|
||||||
public static final String Manager = "manager";
|
public static final String Manager = "manager";
|
||||||
|
public static final String Staff = "Staff";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package com.drinkool.lib.dtos;
|
package com.drinkool.lib.dtos;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class Login {
|
public class Login {
|
||||||
|
|
||||||
public String phone;
|
public String phone;
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
package com.drinkool.lib.dtos;
|
package com.drinkool.lib.dtos;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
public class Signup {
|
public class Signup {
|
||||||
|
|
||||||
public String name;
|
public String name;
|
||||||
|
|||||||
Reference in New Issue
Block a user