Skip to content

Commit 37eea0d

Browse files
authored
Apartment shortcuts (#294)
1 parent 03073a2 commit 37eea0d

28 files changed

+231
-233
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*.tar.gz
2727
*.rar
2828
target/
29+
data/
2930

3031
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
3132
hs_err_pid*

docker-compose.yml

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,41 @@
1-
version: '3.8'
21
services:
32
mysql:
43
image: mysql:lts
5-
ports:
6-
- "3306:3306"
4+
container_name: mysql
75
environment:
86
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
97
- MYSQL_DATABASE=REMSFAL
8+
ports:
9+
- "3306:3306"
1010

1111
grafana:
12-
networks:
13-
- remsfal
1412
image: grafana/grafana-enterprise
1513
container_name: grafana
1614
restart: unless-stopped
1715
ports:
18-
- '3001:3000'
16+
- '3000:3000'
17+
networks:
18+
- remsfal
1919

2020
prometheus:
2121
image: prom/prometheus
22-
volumes:
23-
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
24-
networks:
25-
- remsfal
22+
container_name: prometheus
2623
ports:
2724
- '9090:9090'
25+
networks:
26+
- remsfal
27+
volumes:
28+
- "./prometheus.yml:/etc/prometheus/prometheus.yml"
2829

2930
zeebe:
3031
image: camunda/zeebe:latest
31-
ports:
32-
- "26500:26500"
32+
container_name: camunda
3333
environment:
3434
- ZEEBE_BROKER_CLUSTER_SIZE=1
3535
- ZEEBE_BROKER_PARTITIONS_COUNT=1
3636
- ZEEBE_BROKER_REPLICATION_FACTOR=1
37+
ports:
38+
- "26500:26500"
3739

3840
minio:
3941
image: minio/minio

remsfal-core/src/main/java/de/remsfal/core/api/ProjectEndpoint.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import de.remsfal.core.api.project.ApartmentEndpoint;
2828
import de.remsfal.core.api.project.BuildingEndpoint;
29+
import de.remsfal.core.api.project.CommercialEndpoint;
2930
import de.remsfal.core.api.project.DefectEndpoint;
3031
import de.remsfal.core.api.project.GarageEndpoint;
3132
import de.remsfal.core.api.project.PropertyEndpoint;
@@ -177,8 +178,9 @@ void deleteProjectMember(
177178

178179
@Path("/{projectId}/" + ApartmentEndpoint.SERVICE)
179180
ApartmentEndpoint getApartmentResource();
180-
181-
// TODO: Implement Commercial Endpoint
181+
182+
@Path("/{projectId}/" + CommercialEndpoint.SERVICE)
183+
CommercialEndpoint getCommercialResource();
182184

183185
@Path("/{projectId}/" + GarageEndpoint.SERVICE)
184186
GarageEndpoint getGarageResource();

remsfal-core/src/main/java/de/remsfal/core/api/project/ApartmentEndpoint.java

-6
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@ Response createApartment(
5757
ApartmentJson getApartment(
5858
@Parameter(description = "ID of the project", required = true)
5959
@PathParam("projectId") @NotNull @UUID String projectId,
60-
@Parameter(description = "ID of the building", required = true)
61-
@PathParam("buildingId") @NotNull @UUID String buildingId,
6260
@Parameter(description = "ID of the apartment", required = true)
6361
@PathParam("apartmentId") @NotNull @UUID String apartmentId
6462
);
@@ -73,8 +71,6 @@ ApartmentJson getApartment(
7371
ApartmentJson updateApartment(
7472
@Parameter(description = "ID of the project", required = true)
7573
@PathParam("projectId") @NotNull @UUID String projectId,
76-
@Parameter(description = "ID of the building", required = true)
77-
@PathParam("buildingId") @NotNull @UUID String buildingId,
7874
@Parameter(description = "ID of the apartment", required = true)
7975
@PathParam("apartmentId") @NotNull @UUID String apartmentId,
8076
@Parameter(description = "Apartment object with information", required = true)
@@ -89,8 +85,6 @@ ApartmentJson updateApartment(
8985
void deleteApartment(
9086
@Parameter(description = "ID of the project", required = true)
9187
@PathParam("projectId") @NotNull @UUID String projectId,
92-
@Parameter(description = "ID of the building", required = true)
93-
@PathParam("buildingId") @NotNull @UUID String buildingId,
9488
@Parameter(description = "ID of the apartment", required = true)
9589
@PathParam("apartmentId") @NotNull @UUID String apartmentId
9690
);

remsfal-core/src/main/java/de/remsfal/core/api/project/BuildingEndpoint.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ void deleteBuilding(
105105

106106
@Path("/{buildingId}/" + ApartmentEndpoint.SERVICE)
107107
ApartmentEndpoint getApartmentResource();
108-
109-
// TODO: Implement Commercial Endpoint
108+
109+
@Path("/{buildingId}/" + CommercialEndpoint.SERVICE)
110+
CommercialEndpoint getCommercialResource();
110111

111112
@Path("/{buildingId}/" + GarageEndpoint.SERVICE)
112113
GarageEndpoint getGarageResource();

remsfal-core/src/main/java/de/remsfal/core/api/project/CommercialEndpoint.java

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package de.remsfal.core.api.project;
22

3-
import de.remsfal.core.api.ProjectEndpoint;
43
import de.remsfal.core.validation.PatchValidation;
54
import de.remsfal.core.validation.PostValidation;
65
import de.remsfal.core.validation.UUID;
@@ -30,10 +29,6 @@
3029
/**
3130
* Endpoint for managing Commercial properties within buildings.
3231
*/
33-
@Path(ProjectEndpoint.CONTEXT + "/" + ProjectEndpoint.VERSION + "/"
34-
+ ProjectEndpoint.SERVICE + "/{projectId}/" + PropertyEndpoint.SERVICE
35-
+ "/{propertyId}/" + BuildingEndpoint.SERVICE
36-
+ "/{buildingId}/" + CommercialEndpoint.SERVICE)
3732
public interface CommercialEndpoint {
3833

3934
String SERVICE = "commercials";
@@ -61,8 +56,6 @@ Response createCommercial(
6156
CommercialJson getCommercial(
6257
@Parameter(description = "ID of the project", required = true)
6358
@PathParam("projectId") @NotNull @UUID String projectId,
64-
@Parameter(description = "ID of the building", required = true)
65-
@PathParam("buildingId") @NotNull @UUID String buildingId,
6659
@Parameter(description = "ID of the commercial unit", required = true)
6760
@PathParam("commercialId") @NotNull @UUID String commercialId
6861
);
@@ -77,8 +70,6 @@ CommercialJson getCommercial(
7770
CommercialJson updateCommercial(
7871
@Parameter(description = "ID of the project", required = true)
7972
@PathParam("projectId") @NotNull @UUID String projectId,
80-
@Parameter(description = "ID of the building", required = true)
81-
@PathParam("buildingId") @NotNull @UUID String buildingId,
8273
@Parameter(description = "ID of the commercial unit", required = true)
8374
@PathParam("commercialId") @NotNull @UUID String commercialId,
8475
@Parameter(description = "Commercial unit object with information", required = true)
@@ -93,9 +84,8 @@ CommercialJson updateCommercial(
9384
void deleteCommercial(
9485
@Parameter(description = "ID of the project", required = true)
9586
@PathParam("projectId") @NotNull @UUID String projectId,
96-
@Parameter(description = "ID of the building", required = true)
97-
@PathParam("buildingId") @NotNull @UUID String buildingId,
9887
@Parameter(description = "ID of the commercial unit", required = true)
9988
@PathParam("commercialId") @NotNull @UUID String commercialId
10089
);
90+
10191
}

remsfal-core/src/main/java/de/remsfal/core/api/project/GarageEndpoint.java

-12
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ Response createGarage(
5757
GarageJson getGarage(
5858
@Parameter(description = "ID of the project", required = true)
5959
@PathParam("projectId") String projectId,
60-
@Parameter(description = "ID of the property", required = true)
61-
@PathParam("propertyId") String propertyId,
62-
@Parameter(description = "ID of the building", required = true)
63-
@PathParam("buildingId") String buildingId,
6460
@Parameter(description = "ID of the garage", required = true)
6561
@PathParam("garageId") String garageId
6662
);
@@ -81,10 +77,6 @@ GarageJson getGarage(
8177
GarageJson updateGarage(
8278
@Parameter(description = "ID of the project", required = true)
8379
@PathParam("projectId") @NotNull @UUID String projectId,
84-
@Parameter(description = "ID of the property", required = true)
85-
@PathParam("propertyId") @NotNull @UUID String propertyId,
86-
@Parameter(description = "ID of the building", required = true)
87-
@PathParam("buildingId") @NotNull @UUID String buildingId,
8880
@Parameter(description = "ID of the garage", required = true)
8981
@PathParam("garageId") @NotNull @UUID String garageId,
9082
@Parameter(description = "Garage information", required = true)
@@ -105,10 +97,6 @@ GarageJson updateGarage(
10597
void deleteGarage(
10698
@Parameter(description = "ID of the project", required = true)
10799
@PathParam("projectId") @NotNull @UUID String projectId,
108-
@Parameter(description = "ID of the property", required = true)
109-
@PathParam("propertyId") @NotNull @UUID String propertyId,
110-
@Parameter(description = "ID of the building", required = true)
111-
@PathParam("buildingId") @NotNull @UUID String buildingId,
112100
@Parameter(description = "ID of the garage", required = true)
113101
@PathParam("garageId") @NotNull @UUID String garageId
114102
);

remsfal-service/src/main/java/de/remsfal/service/boundary/ProjectResource.java

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import de.remsfal.service.boundary.authentication.RemsfalPrincipal;
2525
import de.remsfal.service.boundary.project.ApartmentResource;
2626
import de.remsfal.service.boundary.project.BuildingResource;
27+
import de.remsfal.service.boundary.project.CommercialResource;
2728
import de.remsfal.service.boundary.project.DefectResource;
2829
import de.remsfal.service.boundary.project.GarageResource;
2930
import de.remsfal.service.boundary.project.PropertyResource;
@@ -63,6 +64,9 @@ public class ProjectResource implements ProjectEndpoint {
6364
@Inject
6465
Instance<ApartmentResource> apartmentResource;
6566

67+
@Inject
68+
Instance<CommercialResource> commercialResource;
69+
6670
@Inject
6771
Instance<GarageResource> garageResource;
6872

@@ -153,6 +157,11 @@ public ApartmentResource getApartmentResource() {
153157
return resourceContext.initResource(apartmentResource.get());
154158
}
155159

160+
@Override
161+
public CommercialResource getCommercialResource() {
162+
return resourceContext.initResource(commercialResource.get());
163+
}
164+
156165
@Override
157166
public GarageResource getGarageResource() {
158167
return resourceContext.initResource(garageResource.get());

remsfal-service/src/main/java/de/remsfal/service/boundary/authentication/JWTManager.java

+9-13
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import com.nimbusds.jose.JWSVerifier;
55
import com.nimbusds.jose.crypto.RSASSAVerifier;
66
import com.nimbusds.jwt.JWTClaimsSet;
7+
8+
import de.remsfal.service.boundary.exception.InvalidTokenException;
79
import de.remsfal.service.boundary.exception.TokenExpiredException;
8-
import de.remsfal.service.boundary.exception.UnauthorizedException;
910
import io.smallrye.jwt.algorithm.SignatureAlgorithm;
1011
import io.smallrye.jwt.build.Jwt;
1112
import jakarta.annotation.PostConstruct;
@@ -58,7 +59,7 @@ public final String createJWT(SessionInfo sessionInfo) {
5859
.algorithm(SignatureAlgorithm.RS256).header("typ", "JWT").sign(privateKey);
5960
}
6061

61-
public SessionInfo verifyJWT(String jwt) throws UnauthorizedException, TokenExpiredException {
62+
public SessionInfo verifyJWT(String jwt) {
6263
return verifyJWT(jwt, false);
6364
}
6465

@@ -72,37 +73,32 @@ public JWTClaimsSet verifyTokenManually(String jwt, PublicKey publicKey) {
7273
if (jwsObject.verify(verifier)) {
7374
return JWTClaimsSet.parse(jwsObject.getPayload().toJSONObject());
7475
} else {
75-
throw new UnauthorizedException("Invalid token");
76+
throw new InvalidTokenException();
7677
}
7778
} catch (Exception e) {
78-
throw new UnauthorizedException("Invalid token");
79+
throw new InvalidTokenException(e);
7980
}
8081
}
8182

82-
public SessionInfo verifyJWT(String jwt, boolean isRefreshToken)
83-
throws UnauthorizedException, TokenExpiredException {
84-
85-
83+
public SessionInfo verifyJWT(String jwt, boolean isRefreshToken) {
8684
JWTClaimsSet claimsSet = verifyTokenManually(jwt, publicKey);
8785

8886
if (claimsSet == null) {
89-
throw new UnauthorizedException("Invalid token");
87+
throw new InvalidTokenException();
9088
}
9189
if (isRefreshToken && claimsSet.getClaim("refreshToken") == null) {
92-
throw new UnauthorizedException("Missing refresh token claim in token");
90+
throw new InvalidTokenException("Missing refresh token claim in token");
9391
}
9492
if (claimsSet.getExpirationTime().before(new Date())) {
9593
throw new TokenExpiredException(isRefreshToken ? "Refresh token expired" : "Access token expired");
9694
}
9795
SessionInfo sessionInfo = new SessionInfo(claimsSet);
9896

9997
if (!sessionInfo.isValid()) {
100-
throw new UnauthorizedException("Invalid token");
98+
throw new InvalidTokenException();
10199
}
102100

103101
return sessionInfo;
104-
105-
106102
}
107103

108104
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package de.remsfal.service.boundary.exception;
2+
3+
import de.remsfal.service.boundary.authentication.RemsfalSecurityContext;
4+
import jakarta.ws.rs.NotAuthorizedException;
5+
6+
/**
7+
* @author Alexander Stanik [alexander.stanik@htw-berlin.de]
8+
*/
9+
public class InvalidTokenException extends NotAuthorizedException {
10+
11+
private static final long serialVersionUID = 1L;
12+
13+
/**
14+
* Construct a new "unauthorized" exception.
15+
*/
16+
public InvalidTokenException() {
17+
this("Invalid token");
18+
}
19+
20+
/**
21+
* Construct a new "unauthorized" exception.
22+
*
23+
* @param message the detail message (which is saved for later retrieval
24+
* by the {@link #getMessage()} method).
25+
*/
26+
public InvalidTokenException(String message) {
27+
super(message, RemsfalSecurityContext.BEARER);
28+
}
29+
30+
/**
31+
* Construct a new "unauthorized" exception.
32+
*
33+
* @param message the detail message (which is saved for later retrieval
34+
* by the {@link #getMessage()} method).
35+
* @param cause the underlying cause of the exception.
36+
*/
37+
public InvalidTokenException(Throwable cause) {
38+
super("Invalid token", cause, RemsfalSecurityContext.BEARER);
39+
}
40+
41+
}

remsfal-service/src/main/java/de/remsfal/service/boundary/project/ApartmentResource.java

+9-10
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,25 @@ public Response createApartment(final String projectId, final String buildingId,
3030
}
3131

3232
@Override
33-
public ApartmentJson getApartment(final String projectId, final String buildingId,
34-
final String apartmentId) {
33+
public ApartmentJson getApartment(final String projectId, final String apartmentId) {
3534
checkPrivileges(projectId);
36-
final ApartmentModel model = controller.getApartment(projectId, buildingId, apartmentId);
35+
final ApartmentModel model = controller.getApartment(projectId, apartmentId);
3736

3837
return ApartmentJson.valueOf(model);
3938
}
4039

4140
@Override
42-
public ApartmentJson updateApartment(final String projectId, final String buildingId,
43-
final String apartmentId, final ApartmentJson apartment) {
41+
public ApartmentJson updateApartment(final String projectId, final String apartmentId,
42+
final ApartmentJson apartment) {
4443
checkPrivileges(projectId);
45-
return ApartmentJson.valueOf(controller.updateApartment(
46-
projectId, buildingId, apartmentId, apartment));
44+
return ApartmentJson
45+
.valueOf(controller.updateApartment(projectId, apartmentId, apartment));
4746
}
4847

4948
@Override
50-
public void deleteApartment(final String projectId, final String buildingId,
51-
final String apartmentId) {
49+
public void deleteApartment(final String projectId, final String apartmentId) {
5250
checkPrivileges(projectId);
53-
controller.deleteApartment(projectId, buildingId, apartmentId);
51+
controller.deleteApartment(projectId, apartmentId);
5452
}
53+
5554
}

remsfal-service/src/main/java/de/remsfal/service/boundary/project/BuildingResource.java

+8
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class BuildingResource extends ProjectSubResource implements BuildingEndp
2121
@Inject
2222
Instance<ApartmentResource> apartmentResource;
2323

24+
@Inject
25+
Instance<CommercialResource> commercialResource;
26+
2427
@Inject
2528
Instance<GarageResource> garageResource;
2629

@@ -61,6 +64,11 @@ public ApartmentResource getApartmentResource() {
6164
return resourceContext.initResource(apartmentResource.get());
6265
}
6366

67+
@Override
68+
public CommercialResource getCommercialResource() {
69+
return resourceContext.initResource(commercialResource.get());
70+
}
71+
6472
@Override
6573
public GarageResource getGarageResource() {
6674
return resourceContext.initResource(garageResource.get());

0 commit comments

Comments
 (0)