Skip to content

Commit

Permalink
Merge pull request #157 from GetStream/gdpr
Browse files Browse the repository at this point in the history
[MOD-0]chore: add export ID, batch delete endpoint
  • Loading branch information
itsmeadi authored Nov 11, 2024
2 parents 7781ff1 + 72eb9b6 commit 8328987
Show file tree
Hide file tree
Showing 11 changed files with 542 additions and 2 deletions.
17 changes: 17 additions & 0 deletions src/main/java/io/getstream/client/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.util.Date;
import java.util.List;
import java.util.Map;

import io.getstream.core.utils.Auth;
import java8.util.concurrent.CompletableFuture;

public final class Client {
Expand Down Expand Up @@ -363,4 +365,19 @@ CompletableFuture<Response> userProfile(String id) throws StreamException {
final Token token = buildUsersToken(secret, TokenAction.READ);
return stream.getUser(token, id, true);
}

public CompletableFuture<Object> deleteActivities(BatchDeleteActivitiesRequest request) throws StreamException {
final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE);
return stream.deleteActivities(token, request);
}

public CompletableFuture<Object> deleteReactions(BatchDeleteReactionsRequest request) throws StreamException {
final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.WRITE);
return stream.deleteReactions(token, request);
}

public CompletableFuture<ExportIDsResponse> exportUserActivities(String userId) throws StreamException {
final Token token = buildDataPrivacyToken(secret, Auth.TokenAction.READ);
return stream.exportUserActivities(token, userId);
}
}
47 changes: 47 additions & 0 deletions src/main/java/io/getstream/core/Stream.java
Original file line number Diff line number Diff line change
Expand Up @@ -525,4 +525,51 @@ public CompletableFuture<Response> updateUser(Token token, String userID, Data u
throw new StreamException(e);
}
}

public CompletableFuture<Object> deleteActivities(Token token, BatchDeleteActivitiesRequest request) throws StreamException {
try {
final URL url = deleteActivitiesURL(baseURL);
final byte[] payload = toJSON(request);
io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload);
return httpClient.execute(httpRequest).thenApply(response -> null);
} catch (Exception e) {
throw new StreamException(e);
}
}

public CompletableFuture<Object> deleteReactions(Token token, BatchDeleteReactionsRequest request) throws StreamException {
try {

final URL url = deleteReactionsURL(baseURL);
final byte[] payload = toJSON(request);
io.getstream.core.http.Request httpRequest = buildPost(url, key, token, payload);

return httpClient.execute(httpRequest).thenApply(response -> null);
} catch (Exception e) {
throw new StreamException(e);
}
}

public CompletableFuture<ExportIDsResponse> exportUserActivities(Token token, String userId) throws StreamException {
if (userId == null || userId.isEmpty()) {
throw new IllegalArgumentException("User ID can't be null or empty");
}

try {
final URL url = buildExportIDsURL(baseURL, userId);
io.getstream.core.http.Request request = buildGet(url, key, token);
return httpClient
.execute(request)
.thenApply(
response -> {
try {
return deserialize(response, ExportIDsResponse.class);
} catch (StreamException | IOException e) {
throw new CompletionException(e);
}
});
} catch (MalformedURLException | URISyntaxException e) {
throw new StreamException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.getstream.core.models;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class BatchDeleteActivitiesRequest {

private final List<ActivityToDelete> activities;

public BatchDeleteActivitiesRequest(List<ActivityToDelete> activities) {
this.activities = activities;
}

public List<ActivityToDelete> getActivities() {
return activities;
}

public static class ActivityToDelete {
private final String id;
private final List<String> removeFromFeeds;

public ActivityToDelete(
@JsonProperty("id") String id,
@JsonProperty("remove_from_feeds") List<String> removeFromFeeds) {
this.id = id;
this.removeFromFeeds = removeFromFeeds;
}

public String getId() {
return id;
}

public List<String> getRemoveFromFeeds() {
return removeFromFeeds;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.getstream.core.models;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

@JsonInclude(JsonInclude.Include.NON_NULL)
public class BatchDeleteReactionsRequest {

private final List<String> ids;

public BatchDeleteReactionsRequest(@JsonProperty("ids") List<String> ids) {
this.ids = ids;
}

public List<String> getIds() {
return ids;
}
}
35 changes: 35 additions & 0 deletions src/main/java/io/getstream/core/models/ExportIDsResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.getstream.core.models;
import com.fasterxml.jackson.annotation.JsonProperty;

public class ExportIDsResponse {
@JsonProperty("export")
private ExportIDsResult export;

@JsonProperty("duration")
private String duration;

// No-argument constructor
public ExportIDsResponse() {
}

// Constructor with parameters
public ExportIDsResponse(String duration) {
this.duration = duration;
}

public ExportIDsResult getExport() {
return export;
}

public void setExport(ExportIDsResult export) {
this.export = export;
}

public String getDuration() {
return duration;
}

public void setDuration(String duration) {
this.duration = duration;
}
}
62 changes: 62 additions & 0 deletions src/main/java/io/getstream/core/models/ExportIDsResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package io.getstream.core.models;

import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;

public class ExportIDsResult {
@JsonProperty("user_id")
private String userId;

@JsonProperty("activity_count")
private int activityCount;

@JsonProperty("activity_ids")
private List<String> activityIds;

@JsonProperty("reaction_count")
private int reactionCount;

@JsonProperty("reaction_ids")
private List<String> reactionIds;

// Getters and Setters
public String getUserId() {
return userId;
}

public void setUserId(String userId) {
this.userId = userId;
}

public int getActivityCount() {
return activityCount;
}

public void setActivityCount(int activityCount) {
this.activityCount = activityCount;
}

public List<String> getActivityIds() {
return activityIds;
}

public void setActivityIds(List<String> activityIds) {
this.activityIds = activityIds;
}

public int getReactionCount() {
return reactionCount;
}

public void setReactionCount(int reactionCount) {
this.reactionCount = reactionCount;
}

public List<String> getReactionIds() {
return reactionIds;
}

public void setReactionIds(List<String> reactionIds) {
this.reactionIds = reactionIds;
}
}
8 changes: 7 additions & 1 deletion src/main/java/io/getstream/core/options/Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ enum OpType {
ID_GREATER_THAN("id_gt"),
ID_LESS_THAN_OR_EQUAL("id_lte"),
ID_LESS_THAN("id_lt"),
REFRESH("refresh");
REFRESH("refresh"),
DISCARD_DELETED_ACTIVITIES("discard_deleted_activities");

private String operator;

Expand Down Expand Up @@ -46,6 +47,11 @@ public Filter idGreaterThanEqual(String id) {
return this;
}

public Filter discardDeletedActivities() {
ops.add(new OpEntry(OpType.DISCARD_DELETED_ACTIVITIES, "true"));
return this;
}

public Filter idLessThan(String id) {
ops.add(new OpEntry(OpType.ID_LESS_THAN, id));
return this;
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/io/getstream/core/utils/Auth.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public enum TokenResource {
PERSONALIZATION("personalization"),
REACTIONS("reactions"),
USERS("users"),
MODERATION("moderation");
MODERATION("moderation"),
DATAPRIVACY("data_privacy");

private final String resource;

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

public static Token buildDataPrivacyToken(String secret, TokenAction action) {
return buildBackendToken(secret, TokenResource.DATAPRIVACY, action, "*");
}

public static Token buildAnalyticsToken(String secret, TokenAction action) {
return buildBackendToken(secret, TokenResource.ANALYTICS, action, "*");
}
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/io/getstream/core/utils/Routes.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public final class Routes {
private static final String usersPath = "user/";
private static final String followStatsPath = "stats/follow/";

private static final String exportIDsPath = "data_privacy/export_ids/";
private static final String deleteActivitiesPath = "data_privacy/delete_activities/";
private static final String deleteReactionsPath = "data_privacy/delete_reactions/";

private Routes() {
/* nothing to see here */
}
Expand Down Expand Up @@ -118,6 +122,18 @@ public static URL buildModerationFlagURL(URL baseURL) throws MalformedURLExcepti
return new URL(baseURL, basePath + moderationFlagPath);
}

public static URL buildExportIDsURL(URL baseURL, String userID) throws MalformedURLException {
return new URL(baseURL, basePath + exportIDsPath+userID);
}

public static URL deleteActivitiesURL(URL baseURL) throws MalformedURLException {
return new URL(baseURL, basePath + deleteActivitiesPath);
}

public static URL deleteReactionsURL(URL baseURL) throws MalformedURLException {
return new URL(baseURL, basePath + deleteReactionsPath);
}

public static URL followStatsPath(URL baseURL) throws MalformedURLException {
return new URL(baseURL, basePath + followStatsPath);
}
Expand Down
Loading

0 comments on commit 8328987

Please sign in to comment.