Skip to content

Commit dbe6492

Browse files
duhizjameagilelab-tmnd1991
authored andcommitted
fixed share serde on getShare call
fixed recipients and id of share basic authorization based on the request principal auth into separate class forbidden exception handling + owner of share authorized formatting
1 parent 689fce5 commit dbe6492

File tree

14 files changed

+410
-184
lines changed

14 files changed

+410
-184
lines changed

server/app/src/main/java/io/whitefox/api/deltasharing/server/DeltaSharesApiImpl.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55
import io.whitefox.api.deltasharing.ClientCapabilitiesMapper;
66
import io.whitefox.api.deltasharing.DeltaMappers;
77
import io.whitefox.api.deltasharing.encoders.DeltaPageTokenEncoder;
8-
import io.whitefox.api.deltasharing.model.v1.generated.ListSchemasResponse;
9-
import io.whitefox.api.deltasharing.model.v1.generated.ListShareResponse;
10-
import io.whitefox.api.deltasharing.model.v1.generated.ListTablesResponse;
11-
import io.whitefox.api.deltasharing.model.v1.generated.QueryRequest;
8+
import io.whitefox.api.deltasharing.model.v1.generated.*;
129
import io.whitefox.api.deltasharing.serializers.TableMetadataSerializer;
1310
import io.whitefox.api.deltasharing.serializers.TableQueryResponseSerializer;
1411
import io.whitefox.api.deltasharing.server.v1.generated.DeltaApiApi;
@@ -51,8 +48,10 @@ public DeltaSharesApiImpl(
5148
@Override
5249
public Response getShare(String share) {
5350
return wrapExceptions(
54-
() ->
55-
optionalToNotFound(shareService.getShare(share), s -> Response.ok(s).build()),
51+
() -> optionalToNotFound(shareService.getShare(share), s -> {
52+
var resultShare = new Share().name(s.name()).id(s.id());
53+
return Response.ok(resultShare).build();
54+
}),
5655
exceptionToResponse);
5756
}
5857

@@ -85,9 +84,15 @@ public Response getTableMetadata(
8584
clientCapabilitiesMapper.parseDeltaSharingCapabilities(deltaSharingCapabilities);
8685
return optionalToNotFound(
8786
deltaSharesService.getTableMetadata(
88-
share, schema, table, startingTimestamp, clientCapabilities),
87+
share,
88+
schema,
89+
table,
90+
startingTimestamp,
91+
clientCapabilities,
92+
getRequestPrincipal()),
8993
m -> optionalToNotFound(
90-
deltaSharesService.getTableVersion(share, schema, table, startingTimestamp),
94+
deltaSharesService.getTableVersion(
95+
share, schema, table, startingTimestamp, getRequestPrincipal()),
9196
v -> Response.ok(
9297
tableResponseSerializer.serialize(
9398
DeltaMappers.toTableResponseMetadata(m)),
@@ -104,12 +109,12 @@ public Response getTableMetadata(
104109
@Override
105110
public Response getTableVersion(
106111
String share, String schema, String table, String startingTimestampStr) {
107-
108112
return wrapExceptions(
109113
() -> {
110114
var startingTimestamp = parseTimestamp(startingTimestampStr);
111115
return optionalToNotFound(
112-
deltaSharesService.getTableVersion(share, schema, table, startingTimestamp),
116+
deltaSharesService.getTableVersion(
117+
share, schema, table, startingTimestamp, getRequestPrincipal()),
113118
t -> Response.ok().header(DELTA_TABLE_VERSION_HEADER, t).build());
114119
},
115120
exceptionToResponse);
@@ -120,7 +125,10 @@ public Response listALLTables(String share, Integer maxResults, String pageToken
120125
return wrapExceptions(
121126
() -> optionalToNotFound(
122127
deltaSharesService.listTablesOfShare(
123-
share, parseToken(pageToken), Optional.ofNullable(maxResults)),
128+
share,
129+
parseToken(pageToken),
130+
Optional.ofNullable(maxResults),
131+
getRequestPrincipal()),
124132
c -> Response.ok(c.getToken()
125133
.map(t -> new ListTablesResponse()
126134
.items(mapList(c.getContent(), DeltaMappers::table2api))
@@ -136,7 +144,11 @@ public Response listSchemas(String share, Integer maxResults, String pageToken)
136144
return wrapExceptions(
137145
() -> optionalToNotFound(
138146
deltaSharesService
139-
.listSchemas(share, parseToken(pageToken), Optional.ofNullable(maxResults))
147+
.listSchemas(
148+
share,
149+
parseToken(pageToken),
150+
Optional.ofNullable(maxResults),
151+
getRequestPrincipal())
140152
.map(ct -> ct.getToken()
141153
.map(t -> new ListSchemasResponse()
142154
.nextPageToken(tokenEncoder.encodePageToken(t))
@@ -151,8 +163,8 @@ public Response listSchemas(String share, Integer maxResults, String pageToken)
151163
public Response listShares(Integer maxResults, String pageToken) {
152164
return wrapExceptions(
153165
() -> {
154-
var c =
155-
deltaSharesService.listShares(parseToken(pageToken), Optional.ofNullable(maxResults));
166+
var c = deltaSharesService.listShares(
167+
parseToken(pageToken), Optional.ofNullable(maxResults), getRequestPrincipal());
156168
var response =
157169
new ListShareResponse().items(mapList(c.getContent(), DeltaMappers::share2api));
158170
return Response.ok(c.getToken()
@@ -168,7 +180,11 @@ public Response listTables(String share, String schema, Integer maxResults, Stri
168180
return wrapExceptions(
169181
() -> optionalToNotFound(
170182
deltaSharesService.listTables(
171-
share, schema, parseToken(pageToken), Optional.ofNullable(maxResults)),
183+
share,
184+
schema,
185+
parseToken(pageToken),
186+
Optional.ofNullable(maxResults),
187+
getRequestPrincipal()),
172188
c -> Response.ok(c.getToken()
173189
.map(t -> new ListTablesResponse()
174190
.items(mapList(c.getContent(), DeltaMappers::table2api))
@@ -201,7 +217,8 @@ public Response queryTable(
201217
schema,
202218
table,
203219
DeltaMappers.api2ReadTableRequest(queryRequest),
204-
clientCapabilitiesMapper.parseDeltaSharingCapabilities(deltaSharingCapabilities));
220+
clientCapabilitiesMapper.parseDeltaSharingCapabilities(deltaSharingCapabilities),
221+
getRequestPrincipal());
205222
var serializedReadResult =
206223
tableQueryResponseSerializer.serialize(DeltaMappers.readTableResult2api(readResult));
207224
return Response.ok(serializedReadResult, ndjsonMediaType)

server/app/src/main/java/io/whitefox/api/server/ApiUtils.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import io.whitefox.core.Principal;
66
import io.whitefox.core.services.exceptions.AlreadyExists;
77
import io.whitefox.core.services.exceptions.NotFound;
8+
import jakarta.ws.rs.ForbiddenException;
89
import jakarta.ws.rs.core.Response;
910
import java.sql.Timestamp;
1011
import java.time.OffsetDateTime;
@@ -45,6 +46,12 @@ public interface ApiUtils extends DeltaHeaders {
4546
.errorCode("BAD REQUEST - timestamp provided is not formatted correctly")
4647
.message(ExceptionUtil.generateStackTrace(t)))
4748
.build();
49+
} else if (t instanceof ForbiddenException) {
50+
return Response.status(Response.Status.FORBIDDEN)
51+
.entity(new CommonErrorResponse()
52+
.errorCode("FORBIDDEN ACCESS")
53+
.message(ExceptionUtil.generateStackTrace(t)))
54+
.build();
4855
} else {
4956
return Response.status(Response.Status.BAD_GATEWAY)
5057
.entity(new CommonErrorResponse()
@@ -68,6 +75,12 @@ default Response notFoundResponse() {
6875
.build();
6976
}
7077

78+
default Response forbiddenResponse() {
79+
return Response.status(Response.Status.FORBIDDEN)
80+
.entity(new CommonErrorResponse().errorCode("2").message("UNAUTHORIZED ACCESS"))
81+
.build();
82+
}
83+
7184
default <T> Response optionalToNotFound(Optional<T> opt, Function<T, Response> fn) {
7285
return opt.map(fn).orElse(notFoundResponse());
7386
}

server/app/src/test/java/io/whitefox/api/deltasharing/SampleTables.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,39 @@ public static InternalTable s3IcebergTable1(
5555
public static final InternalTable deltaTableWithHistory1 = deltaTable("delta-table-with-history");
5656

5757
public static StorageManager createStorageManager() {
58-
return new InMemoryStorageManager(List.of(new io.whitefox.core.Share(
59-
"name",
60-
"key",
61-
Map.of(
62-
"default",
63-
new io.whitefox.core.Schema(
58+
return new InMemoryStorageManager(List.of(
59+
new io.whitefox.core.Share(
60+
"name",
61+
"key",
62+
Map.of(
6463
"default",
65-
List.of(
66-
new SharedTable("table1", "default", "name", deltaTable1),
67-
new SharedTable(
68-
"table-with-history", "default", "name", deltaTableWithHistory1),
69-
new SharedTable("icebergtable1", "default", "name", icebergtable1),
70-
new SharedTable("icebergtable2", "default", "name", icebergtable2)),
71-
"name")),
72-
testPrincipal,
73-
0L)));
64+
new io.whitefox.core.Schema(
65+
"default",
66+
List.of(
67+
new SharedTable("table1", "default", "name", deltaTable1),
68+
new SharedTable(
69+
"table-with-history", "default", "name", deltaTableWithHistory1),
70+
new SharedTable("icebergtable1", "default", "name", icebergtable1),
71+
new SharedTable("icebergtable2", "default", "name", icebergtable2)),
72+
"name")),
73+
testPrincipal,
74+
0L),
75+
new io.whitefox.core.Share(
76+
"noauthShare",
77+
"key",
78+
Map.of(
79+
"default",
80+
new io.whitefox.core.Schema(
81+
"default",
82+
List.of(
83+
new SharedTable("table1", "default", "name", deltaTable1),
84+
new SharedTable(
85+
"table-with-history", "default", "name", deltaTableWithHistory1),
86+
new SharedTable("icebergtable1", "default", "name", icebergtable1),
87+
new SharedTable("icebergtable2", "default", "name", icebergtable2)),
88+
"name")),
89+
new Principal("Mr. White"),
90+
0L)));
7491
}
7592

7693
public static final ParquetMetadata deltaTable1Metadata = ParquetMetadata.builder()

server/app/src/test/java/io/whitefox/api/deltasharing/server/DeltaSharesApiImplAwsTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void updateStorageManagerWithS3Tables() {
9191
"s3share",
9292
s3IcebergTable1(s3TestConfig, awsGlueTestConfig))),
9393
"s3share")),
94-
new Principal("Mr fox"),
94+
new Principal("Mr. Fox"),
9595
0L));
9696
}
9797

server/app/src/test/java/io/whitefox/api/deltasharing/server/DeltaSharesApiImplTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ public void listNotFoundSchemas() {
108108
.body("message", is("NOT FOUND"));
109109
}
110110

111+
@Test
112+
public void listSchemasNoAuth() {
113+
given()
114+
.when()
115+
.filter(deltaFilter)
116+
.get("delta-api/v1/shares/{share}/schemas", "noauthShare")
117+
.then()
118+
.statusCode(403);
119+
}
120+
111121
@Test
112122
public void listSchemas() {
113123
given()

server/app/src/test/java/io/whitefox/api/server/ShareV1ApiImplTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ void createShare() {
5757
.statusCode(201)
5858
.body("name", is("share1"))
5959
.body("comment", is(nullValue()))
60-
.body("recipients", is(hasSize(0)))
60+
.body("recipients", is(hasSize(1)))
6161
.body("schemas", is(hasSize(0)))
6262
.body("createdAt", is(0))
6363
.body("createdBy", is("Mr. Fox"))
@@ -89,7 +89,7 @@ void addRecipientsToShare() {
8989
.statusCode(200)
9090
.body("name", is("share1"))
9191
.body("comment", is(nullValue()))
92-
.body("recipients", is(hasSize(3)))
92+
.body("recipients", is(hasSize(4)))
9393
.body("schemas", is(hasSize(0)))
9494
.body("createdAt", is(0))
9595
.body("createdBy", is("Mr. Fox"))
@@ -105,7 +105,7 @@ void addSameRecipientTwice() {
105105
.statusCode(200)
106106
.body("name", is("share1"))
107107
.body("comment", is(nullValue()))
108-
.body("recipients", is(hasSize(3)))
108+
.body("recipients", is(hasSize(4)))
109109
.body("schemas", is(hasSize(0)))
110110
.body("createdAt", is(0))
111111
.body("createdBy", is("Mr. Fox"))
@@ -121,7 +121,7 @@ void addAnotherRecipient() {
121121
.statusCode(200)
122122
.body("name", is("share1"))
123123
.body("comment", is(nullValue()))
124-
.body("recipients", is(hasSize(4)))
124+
.body("recipients", is(hasSize(5)))
125125
.body("schemas", is(hasSize(0)))
126126
.body("createdAt", is(0))
127127
.body("createdBy", is("Mr. Fox"))
@@ -143,7 +143,7 @@ public void createSchema() {
143143
.statusCode(201)
144144
.body("name", is("share1"))
145145
.body("comment", is(nullValue()))
146-
.body("recipients", is(hasSize(4)))
146+
.body("recipients", is(hasSize(5)))
147147
.body("schemas", is(hasSize(1)))
148148
.body("schemas[0]", is("schema1"))
149149
.body("createdAt", is(0))
@@ -185,7 +185,7 @@ public void addTableToSchema() {
185185
.statusCode(201)
186186
.body("name", is("share1"))
187187
.body("comment", is(nullValue()))
188-
.body("recipients", is(hasSize(4)))
188+
.body("recipients", is(hasSize(5)))
189189
.body("schemas", is(hasSize(1)))
190190
.body("schemas[0]", is("schema1"))
191191
.body("createdAt", is(0))
@@ -200,7 +200,7 @@ ValidatableResponse createEmptyShare(String name) {
200200
.when()
201201
.filter(whitefoxFilter)
202202
.body(
203-
new CreateShareInput().name(name).recipients(List.of()).schemas(List.of()),
203+
new CreateShareInput().name(name).recipients(List.of("Mr. Fox")).schemas(List.of()),
204204
new Jackson2Mapper((cls, charset) -> objectMapper))
205205
.header(new Header("Content-Type", "application/json"))
206206
.post("/whitefox-api/v1/shares")
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
quarkus.http.test-port=8080
1+
quarkus.http.test-port=8080
2+
quarkus.test.arg-line=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005

server/core/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ dependencies {
1616
implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
1717
// QUARKUS
1818
compileOnly("jakarta.enterprise:jakarta.enterprise.cdi-api")
19-
compileOnly("jakarta.ws.rs:jakarta.ws.rs-api")
19+
implementation("jakarta.ws.rs:jakarta.ws.rs-api")
2020
compileOnly("org.eclipse.microprofile.config:microprofile-config-api")
21-
21+
implementation("org.glassfish.jersey.core:jersey-common:3.1.2")
2222

2323
testFixturesImplementation("jakarta.inject:jakarta.inject-api")
2424
testFixturesImplementation("org.eclipse.microprofile.config:microprofile-config-api")
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.whitefox.core;
2+
3+
import jakarta.enterprise.context.ApplicationScoped;
4+
import lombok.Data;
5+
6+
public interface WhitefoxAuthorization {
7+
8+
Boolean authorize(Share share, Principal principal);
9+
10+
@Data
11+
@ApplicationScoped
12+
class WhitefoxSimpleAuthorization implements WhitefoxAuthorization {
13+
14+
@Override
15+
public Boolean authorize(Share share, Principal principal) {
16+
return share.recipients().contains(principal) || share.owner().equals(principal);
17+
}
18+
}
19+
}

server/core/src/main/java/io/whitefox/core/services/DeltaSharesService.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,49 @@
1313
public interface DeltaSharesService {
1414

1515
Optional<Long> getTableVersion(
16-
String share, String schema, String table, Optional<Timestamp> startingTimestamp);
16+
String share,
17+
String schema,
18+
String table,
19+
Optional<Timestamp> startingTimestamp,
20+
Principal principal);
1721

1822
ContentAndToken<List<Share>> listShares(
19-
Optional<ContentAndToken.Token> nextPageToken, Optional<Integer> maxResults);
23+
Optional<ContentAndToken.Token> nextPageToken,
24+
Optional<Integer> maxResults,
25+
Principal currentPrincipal);
2026

2127
Optional<Metadata> getTableMetadata(
2228
String share,
2329
String schema,
2430
String table,
2531
Optional<Timestamp> startingTimestamp,
26-
ClientCapabilities clientCapabilities);
32+
ClientCapabilities clientCapabilities,
33+
Principal currentPrincipal);
2734

2835
Optional<ContentAndToken<List<Schema>>> listSchemas(
29-
String share, Optional<ContentAndToken.Token> nextPageToken, Optional<Integer> maxResults);
36+
String share,
37+
Optional<ContentAndToken.Token> nextPageToken,
38+
Optional<Integer> maxResults,
39+
Principal currentPrincipal);
3040

3141
Optional<ContentAndToken<List<SharedTable>>> listTables(
3242
String share,
3343
String schema,
3444
Optional<ContentAndToken.Token> nextPageToken,
35-
Optional<Integer> maxResults);
45+
Optional<Integer> maxResults,
46+
Principal currentPrincipal);
3647

3748
Optional<ContentAndToken<List<SharedTable>>> listTablesOfShare(
38-
String share, Optional<ContentAndToken.Token> token, Optional<Integer> maxResults);
49+
String share,
50+
Optional<ContentAndToken.Token> token,
51+
Optional<Integer> maxResults,
52+
Principal currentPrincipal);
3953

4054
ReadTableResult queryTable(
4155
String share,
4256
String schema,
4357
String table,
4458
ReadTableRequest queryRequest,
45-
ClientCapabilities clientCapabilities);
59+
ClientCapabilities clientCapabilities,
60+
Principal currentPrincipal);
4661
}

0 commit comments

Comments
 (0)