Skip to content

Commit 8328987

Browse files
authored
Merge pull request #157 from GetStream/gdpr
[MOD-0]chore: add export ID, batch delete endpoint
2 parents 7781ff1 + 72eb9b6 commit 8328987

File tree

11 files changed

+542
-2
lines changed

11 files changed

+542
-2
lines changed

src/main/java/io/getstream/client/Client.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
import java.util.Date;
2020
import java.util.List;
2121
import java.util.Map;
22+
23+
import io.getstream.core.utils.Auth;
2224
import java8.util.concurrent.CompletableFuture;
2325

2426
public final class Client {
@@ -363,4 +365,19 @@ CompletableFuture<Response> userProfile(String id) throws StreamException {
363365
final Token token = buildUsersToken(secret, TokenAction.READ);
364366
return stream.getUser(token, id, true);
365367
}
368+
369+
public CompletableFuture<Object> deleteActivities(BatchDeleteActivitiesRequest request) throws StreamException {
370+
final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE);
371+
return stream.deleteActivities(token, request);
372+
}
373+
374+
public CompletableFuture<Object> deleteReactions(BatchDeleteReactionsRequest request) throws StreamException {
375+
final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE);
376+
return stream.deleteReactions(token, request);
377+
}
378+
379+
public CompletableFuture<ExportIDsResponse> exportUserActivities(String userId) throws StreamException {
380+
final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.READ);
381+
return stream.exportUserActivities(token, userId);
382+
}
366383
}

src/main/java/io/getstream/core/Stream.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,4 +525,51 @@ public CompletableFuture<Response> updateUser(Token token, String userID, Data u
525525
throw new StreamException(e);
526526
}
527527
}
528+
529+
public CompletableFuture<Object> deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException {
530+
try {
531+
final URL url = deleteActivitiesURL(baseURL);
532+
final byte[] payload = toJSON(request);
533+
io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload);
534+
return httpClient.execute(httpRequest).thenApply(response -> null);
535+
} catch (Exception e) {
536+
throw new StreamException(e);
537+
}
538+
}
539+
540+
public CompletableFuture<Object> deleteReactions(Token token, BatchDeleteReactionsRequest request) throws StreamException {
541+
try {
542+
543+
final URL url = deleteReactionsURL(baseURL);
544+
final byte[] payload = toJSON(request);
545+
io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload);
546+
547+
return httpClient.execute(httpRequest).thenApply(response -> null);
548+
} catch (Exception e) {
549+
throw new StreamException(e);
550+
}
551+
}
552+
553+
public CompletableFuture<ExportIDsResponse> exportUserActivities(Token token, String userId) throws StreamException {
554+
if (userId == null || userId.isEmpty()) {
555+
throw new IllegalArgumentException("User ID can't be null or empty");
556+
}
557+
558+
try {
559+
final URL url = buildExportIDsURL(baseURL, userId);
560+
io.getstream.core.http.Request request = buildGet(url, key, token);
561+
return httpClient
562+
.execute(request)
563+
.thenApply(
564+
response -> {
565+
try {
566+
return deserialize(response, ExportIDsResponse.class);
567+
} catch (StreamException | IOException e) {
568+
throw new CompletionException(e);
569+
}
570+
});
571+
} catch (MalformedURLException | URISyntaxException e) {
572+
throw new StreamException(e);
573+
}
574+
}
528575
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package io.getstream.core.models;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import java.util.List;
6+
7+
@JsonInclude(JsonInclude.Include.NON_NULL)
8+
public class BatchDeleteActivitiesRequest {
9+
10+
private final List<ActivityToDelete> activities;
11+
12+
public BatchDeleteActivitiesRequest(List<ActivityToDelete> activities) {
13+
this.activities = activities;
14+
}
15+
16+
public List<ActivityToDelete> getActivities() {
17+
return activities;
18+
}
19+
20+
public static class ActivityToDelete {
21+
private final String id;
22+
private final List<String> removeFromFeeds;
23+
24+
public ActivityToDelete(
25+
@JsonProperty("id") String id,
26+
@JsonProperty("remove_from_feeds") List<String> removeFromFeeds) {
27+
this.id = id;
28+
this.removeFromFeeds = removeFromFeeds;
29+
}
30+
31+
public String getId() {
32+
return id;
33+
}
34+
35+
public List<String> getRemoveFromFeeds() {
36+
return removeFromFeeds;
37+
}
38+
}
39+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package io.getstream.core.models;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import java.util.List;
6+
7+
@JsonInclude(JsonInclude.Include.NON_NULL)
8+
public class BatchDeleteReactionsRequest {
9+
10+
private final List<String> ids;
11+
12+
public BatchDeleteReactionsRequest(@JsonProperty("ids") List<String> ids) {
13+
this.ids = ids;
14+
}
15+
16+
public List<String> getIds() {
17+
return ids;
18+
}
19+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.getstream.core.models;
2+
import com.fasterxml.jackson.annotation.JsonProperty;
3+
4+
public class ExportIDsResponse {
5+
@JsonProperty("export")
6+
private ExportIDsResult export;
7+
8+
@JsonProperty("duration")
9+
private String duration;
10+
11+
// No-argument constructor
12+
public ExportIDsResponse() {
13+
}
14+
15+
// Constructor with parameters
16+
public ExportIDsResponse(String duration) {
17+
this.duration = duration;
18+
}
19+
20+
public ExportIDsResult getExport() {
21+
return export;
22+
}
23+
24+
public void setExport(ExportIDsResult export) {
25+
this.export = export;
26+
}
27+
28+
public String getDuration() {
29+
return duration;
30+
}
31+
32+
public void setDuration(String duration) {
33+
this.duration = duration;
34+
}
35+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package io.getstream.core.models;
2+
3+
import java.util.List;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
6+
public class ExportIDsResult {
7+
@JsonProperty("user_id")
8+
private String userId;
9+
10+
@JsonProperty("activity_count")
11+
private int activityCount;
12+
13+
@JsonProperty("activity_ids")
14+
private List<String> activityIds;
15+
16+
@JsonProperty("reaction_count")
17+
private int reactionCount;
18+
19+
@JsonProperty("reaction_ids")
20+
private List<String> reactionIds;
21+
22+
// Getters and Setters
23+
public String getUserId() {
24+
return userId;
25+
}
26+
27+
public void setUserId(String userId) {
28+
this.userId = userId;
29+
}
30+
31+
public int getActivityCount() {
32+
return activityCount;
33+
}
34+
35+
public void setActivityCount(int activityCount) {
36+
this.activityCount = activityCount;
37+
}
38+
39+
public List<String> getActivityIds() {
40+
return activityIds;
41+
}
42+
43+
public void setActivityIds(List<String> activityIds) {
44+
this.activityIds = activityIds;
45+
}
46+
47+
public int getReactionCount() {
48+
return reactionCount;
49+
}
50+
51+
public void setReactionCount(int reactionCount) {
52+
this.reactionCount = reactionCount;
53+
}
54+
55+
public List<String> getReactionIds() {
56+
return reactionIds;
57+
}
58+
59+
public void setReactionIds(List<String> reactionIds) {
60+
this.reactionIds = reactionIds;
61+
}
62+
}

src/main/java/io/getstream/core/options/Filter.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ enum OpType {
1010
ID_GREATER_THAN("id_gt"),
1111
ID_LESS_THAN_OR_EQUAL("id_lte"),
1212
ID_LESS_THAN("id_lt"),
13-
REFRESH("refresh");
13+
REFRESH("refresh"),
14+
DISCARD_DELETED_ACTIVITIES("discard_deleted_activities");
1415

1516
private String operator;
1617

@@ -46,6 +47,11 @@ public Filter idGreaterThanEqual(String id) {
4647
return this;
4748
}
4849

50+
public Filter discardDeletedActivities() {
51+
ops.add(new OpEntry(OpType.DISCARD_DELETED_ACTIVITIES, "true"));
52+
return this;
53+
}
54+
4955
public Filter idLessThan(String id) {
5056
ops.add(new OpEntry(OpType.ID_LESS_THAN, id));
5157
return this;

src/main/java/io/getstream/core/utils/Auth.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ public enum TokenResource {
4242
PERSONALIZATION("personalization"),
4343
REACTIONS("reactions"),
4444
USERS("users"),
45-
MODERATION("moderation");
45+
MODERATION("moderation"),
46+
DATAPRIVACY("data_privacy");
4647

4748
private final String resource;
4849

@@ -103,6 +104,10 @@ public static Token buildModerationToken(String secret, TokenAction action) {
103104
return buildBackendToken(secret, TokenResource.MODERATION, action, "*");
104105
}
105106

107+
public static Token buildDataPrivacyToken(String secret, TokenAction action) {
108+
return buildBackendToken(secret, TokenResource.DATAPRIVACY, action, "*");
109+
}
110+
106111
public static Token buildAnalyticsToken(String secret, TokenAction action) {
107112
return buildBackendToken(secret, TokenResource.ANALYTICS, action, "*");
108113
}

src/main/java/io/getstream/core/utils/Routes.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public final class Routes {
2828
private static final String usersPath = "user/";
2929
private static final String followStatsPath = "stats/follow/";
3030

31+
private static final String exportIDsPath = "data_privacy/export_ids/";
32+
private static final String deleteActivitiesPath = "data_privacy/delete_activities/";
33+
private static final String deleteReactionsPath = "data_privacy/delete_reactions/";
34+
3135
private Routes() {
3236
/* nothing to see here */
3337
}
@@ -118,6 +122,18 @@ public static URL buildModerationFlagURL(URL baseURL) throws MalformedURLExcepti
118122
return new URL(baseURL, basePath + moderationFlagPath);
119123
}
120124

125+
public static URL buildExportIDsURL(URL baseURL, String userID) throws MalformedURLException {
126+
return new URL(baseURL, basePath + exportIDsPath+userID);
127+
}
128+
129+
public static URL deleteActivitiesURL(URL baseURL) throws MalformedURLException {
130+
return new URL(baseURL, basePath + deleteActivitiesPath);
131+
}
132+
133+
public static URL deleteReactionsURL(URL baseURL) throws MalformedURLException {
134+
return new URL(baseURL, basePath + deleteReactionsPath);
135+
}
136+
121137
public static URL followStatsPath(URL baseURL) throws MalformedURLException {
122138
return new URL(baseURL, basePath + followStatsPath);
123139
}

0 commit comments

Comments
 (0)