Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 149 additions & 32 deletions src/main/java/org/databunker/DatabunkerproApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
import org.databunker.options.TokenOptions;
import org.databunker.options.PolicyOptions;
import org.databunker.options.PatchOperation;
import org.databunker.options.FileOptions;
import org.databunker.options.OptionsConverter;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
Expand Down Expand Up @@ -347,28 +349,6 @@ public Map<String, Object> listUserVersions(String mode, String identity, Map<St
return makeRequest("UserListVersions", data, requestMetadata);
}

// User Authentication
public Map<String, Object> preloginUser(String mode, String identity, String code, String captchacode, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
data.put("code", code);
data.put("captchacode", captchacode);
return makeRequest("UserPrelogin", data, requestMetadata);
}

public Map<String, Object> loginUser(String mode, String identity, String smscode, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
data.put("smscode", smscode);
return makeRequest("UserLogin", data, requestMetadata);
}

public Map<String, Object> createCaptcha(Map<String, Object> requestMetadata) throws IOException {
return makeRequest("CaptchaCreate", null, requestMetadata);
}

// Create user API Access Token
/**
* Creates an access token for a user
Expand Down Expand Up @@ -608,6 +588,129 @@ public Map<String, Object> listAppDataVersions(String mode, String identity, Str
return makeRequest("AppdataListVersions", data, requestMetadata);
}

// File Storage
/**
* Stores an encrypted file for a user
*
* @param mode User identification mode (login, token, email, phone, custom)
* @param identity User identifier corresponding to the mode
* @param filename Name of the file
* @param filedata File content, base64-encoded
* @param options Optional mimetype, tags and expiration
* @param requestMetadata Optional request metadata
* @return The stored file information, including its fileuuid
* @throws IOException if the request fails
*/
public Map<String, Object> createFile(String mode, String identity, String filename, String filedata, FileOptions options, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
data.put("filename", filename);
data.put("filedata", filedata);
if (options != null) {
data.putAll(OptionsConverter.toMap(options));
}
return makeRequest("FileCreate", data, requestMetadata);
}

public Map<String, Object> createFile(String mode, String identity, String filename, String filedata, Map<String, Object> requestMetadata) throws IOException {
return createFile(mode, identity, filename, filedata, null, requestMetadata);
}

/**
* Gets a user file, selected by fileuuid or filename
*
* @param mode User identification mode
* @param identity User identifier corresponding to the mode
* @param fileuuid UUID of the file, or null
* @param filename Name of the file, or null. The newest match is returned.
* @param raw When true the decrypted bytes are returned directly, or null
* @param requestMetadata Optional request metadata
* @return The file content and metadata
* @throws IOException if the request fails
*/
public Map<String, Object> getFile(String mode, String identity, String fileuuid, String filename, Boolean raw, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
if (fileuuid != null) {
data.put("fileuuid", fileuuid);
}
if (filename != null) {
data.put("filename", filename);
}
if (raw != null) {
data.put("raw", raw);
}
return makeRequest("FileGet", data, requestMetadata);
}

public Map<String, Object> getFile(String mode, String identity, String fileuuid, Map<String, Object> requestMetadata) throws IOException {
return getFile(mode, identity, fileuuid, null, null, requestMetadata);
}

/**
* Lists the metadata of files owned by a user
*
* @param mode User identification mode
* @param identity User identifier corresponding to the mode
* @param tag Return only files carrying this tag, or null. A single tag only.
* @param requestMetadata Optional request metadata
* @return The list of files
* @throws IOException if the request fails
*/
public Map<String, Object> listUserFiles(String mode, String identity, String tag, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
if (tag != null) {
data.put("tag", tag);
}
return makeRequest("FileListUserFiles", data, requestMetadata);
}

public Map<String, Object> listUserFiles(String mode, String identity, Map<String, Object> requestMetadata) throws IOException {
return listUserFiles(mode, identity, null, requestMetadata);
}

/**
* Replaces the complete tag set on a file
*
* @param mode User identification mode
* @param identity User identifier corresponding to the mode
* @param fileuuid UUID of the file to retag
* @param tags The complete replacement tag set
* @param requestMetadata Optional request metadata
* @return The normalised tag set now stored
* @throws IOException if the request fails
*/
public Map<String, Object> replaceFileTags(String mode, String identity, String fileuuid, List<String> tags, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
data.put("fileuuid", fileuuid);
data.put("tags", tags);
return makeRequest("FileReplaceTags", data, requestMetadata);
}

/**
* Deletes a user file
*
* @param mode User identification mode
* @param identity User identifier corresponding to the mode
* @param fileuuid UUID of the file to delete
* @param requestMetadata Optional request metadata
* @return The deletion result
* @throws IOException if the request fails
*/
public Map<String, Object> deleteFile(String mode, String identity, String fileuuid, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("mode", mode);
data.put("identity", identity);
data.put("fileuuid", fileuuid);
return makeRequest("FileDelete", data, requestMetadata);
}

// Legal Basis Management
/**
* Creates a legal basis with typed options
Expand Down Expand Up @@ -1343,6 +1446,30 @@ public Map<String, Object> bulkListAllAuditEvents(String unlockuuid, Map<String,
return bulkListAllAuditEvents(unlockuuid, 0, 10, requestMetadata);
}

/**
* Lists files carrying a tag, across all users in the tenant
*
* @param unlockuuid UUID from bulk list unlock
* @param tag The tag to filter on. A single tag only.
* @param offset Offset for pagination
* @param limit Limit for pagination
* @param requestMetadata Optional request metadata
* @return The list of matching files
* @throws IOException if the request fails
*/
public Map<String, Object> bulkListFilesByTag(String unlockuuid, String tag, int offset, int limit, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("unlockuuid", unlockuuid);
data.put("tag", tag);
data.put("offset", offset);
data.put("limit", limit);
return makeRequest("BulkListFilesByTag", data, requestMetadata);
}

public Map<String, Object> bulkListFilesByTag(String unlockuuid, String tag, Map<String, Object> requestMetadata) throws IOException {
return bulkListFilesByTag(unlockuuid, tag, 0, 10, requestMetadata);
}

public Map<String, Object> bulkListTokens(String unlockuuid, String[] tokens, Map<String, Object> requestMetadata) throws IOException {
Map<String, Object> data = new HashMap<>();
data.put("unlockuuid", unlockuuid);
Expand All @@ -1357,16 +1484,6 @@ public Map<String, Object> bulkDeleteTokens(String unlockuuid, String[] tokens,
return makeRequest("BulkDeleteTokens", data, requestMetadata);
}

// System Configuration
public Map<String, Object> getUIConf() throws IOException {
return makeRequest("TenantGetUIConf", null, null);
}

public Map<String, Object> getTenantConf() throws IOException {
return makeRequest("TenantGetConf", null, null);
}


// Session Management
/**
* Upserts a session with typed options
Expand Down
87 changes: 87 additions & 0 deletions src/main/java/org/databunker/options/FileOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.databunker.options;

import java.util.List;

/**
* Options class for storing a file
*/
public class FileOptions {
private final String mimetype;
private final List<String> tags;
private final String finaltime;
private final String slidingtime;

private FileOptions(Builder builder) {
this.mimetype = builder.mimetype;
this.tags = builder.tags;
this.finaltime = builder.finaltime;
this.slidingtime = builder.slidingtime;
}

/**
* MIME type of the file
* @return The MIME type, or null
*/
public String getMimetype() {
return mimetype;
}

/**
* Tags carried by the file. Tags are lowercased and de-duplicated by the
* server, must match ^[a-z0-9][a-z0-9._-]{0,49}$, and at most 16 are kept.
* @return The tag list, or null
*/
public List<String> getTags() {
return tags;
}

/**
* Absolute expiration time for the file
* @return The final time as a string (e.g., "100d", "1h")
*/
public String getFinaltime() {
return finaltime;
}

/**
* Sliding time period for the file
* @return The sliding time as a string (e.g., "30d", "1h")
*/
public String getSlidingtime() {
return slidingtime;
}

/**
* Builder class for FileOptions
*/
public static class Builder {
private String mimetype;
private List<String> tags;
private String finaltime;
private String slidingtime;

public Builder mimetype(String mimetype) {
this.mimetype = mimetype;
return this;
}

public Builder tags(List<String> tags) {
this.tags = tags;
return this;
}

public Builder finaltime(String finaltime) {
this.finaltime = finaltime;
return this;
}

public Builder slidingtime(String slidingtime) {
this.slidingtime = slidingtime;
return this;
}

public FileOptions build() {
return new FileOptions(this);
}
}
}
24 changes: 24 additions & 0 deletions src/main/java/org/databunker/options/OptionsConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,28 @@ public static Map<String, Object> toMap(PolicyOptions options) {
}
return map;
}

/**
* Converts FileOptions to a Map
* @param options The FileOptions to convert
* @return A Map containing the non-null options
*/
public static Map<String, Object> toMap(FileOptions options) {
Map<String, Object> map = new HashMap<>();
if (options != null) {
if (options.getMimetype() != null) {
map.put("mimetype", options.getMimetype());
}
if (options.getTags() != null) {
map.put("tags", options.getTags());
}
if (options.getFinaltime() != null) {
map.put("finaltime", options.getFinaltime());
}
if (options.getSlidingtime() != null) {
map.put("slidingtime", options.getSlidingtime());
}
}
return map;
}
}
Loading