Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support access only collaboration #1193

Merged
merged 4 commits into from
Aug 11, 2023
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
16 changes: 11 additions & 5 deletions doc/files.md
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ Add a Collaborator
------------------

You can invite another person to collaborate on a file by email with
[`collaborate(String emailAddress, BoxCollaboration.Role role, Boolean notify, Boolean canViewPath)`][share-a-file].
[`collaborate(String emailAddress, BoxCollaboration.Role role, Boolean notify, Boolean canViewPath, Date expiresAt, Boolean isAccessOnly)`][share-a-file].

The `notify` parameter will determine if the user or group will receive an
email notification when being added as a collaborator. This option is only
Expand All @@ -741,7 +741,13 @@ The `canViewPath` parameter allows the invitee to see the entire list of ancesto
folders of the associated file. The user will not gain privileges in any ancestor
folder, but will be able to see the whole path to that file in the owner's account.

Both the `notify` and `canViewPath` parameters can be left as `null`.
The `expiresAt` parameter allows the owner to set a date-time in the future when
the collaboration should expire.

The `isAccessOnly` parameter allows the owner to set the collaboration to be
access only collaboration.

The `notify`, `canViewPath`, `expiresAt` and `isAccessOnly` parameters can be left as `null`.

```java
BoxFile file = new BoxFile(api, "id");
Expand All @@ -750,16 +756,16 @@ BoxCollaboration.Info collabInfo = file.collaborate("[email protected]", BoxC

Alternatively, if you know the user's ID, you can invite them directly
without needing to know their email address with the
[`collaborate(BoxCollaborator user, BoxCollaboration.Role role, Boolean notify, Boolean canViewPath)`][share-a-file-userID]
[`collaborate(BoxCollaborator user, BoxCollaboration.Role role, Boolean notify, Boolean canViewPath, Date expiresAt, Boolean isAccessOnly)`][share-a-file-userID]

```java
BoxUser collaborator = new BoxUser(api, "user-id");
BoxFile file = new BoxFile(api, "file-id");
BoxCollaboration.Info collabInfo = file.collaborate(collaborator, BoxCollaboration.Role.EDITOR, true, true);
```

[share-a-file]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#collaborate-java.lang.String-com.box.sdk.BoxCollaboration.Role-java.lang.Boolean-java.lang.Boolean-
[share-a-file-userID]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#collaborate-com.box.sdk.BoxCollaborator-com.box.sdk.BoxCollaboration.Role-java.lang.Boolean-java.lang.Boolean-
[share-a-file]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#collaborate-java.lang.String-com.box.sdk.BoxCollaboration.Role-java.lang.Boolean-java.lang.Boolean-java.lang.String-java.util.Date-java.lang.Boolean-
[share-a-file-userID]: http://opensource.box.com/box-java-sdk/javadoc/com/box/sdk/BoxFile.html#collaborate-com.box.sdk.BoxCollaborator-com.box.sdk.BoxCollaboration.Role-java.lang.Boolean-java.lang.Boolean-java.lang.String-java.util.Date-java.lang.Boolean-


Get an Embed Link
Expand Down
20 changes: 20 additions & 0 deletions doc/folders.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,28 @@ BoxCollaboration.Info collabInfo = folder.collaborate(collaborator,
BoxCollaboration.Role.EDITOR);
```

You can also create a collaboration with all properties set at once by using the
[`collaborate(BoxCollaborator user, BoxCollaboration.Role role, Boolean notify, Boolean canViewPath, Date expiresAt, Boolean isAccessOnly)`][collaborate3] method.

The `notify` parameter will determine if the user or group will receive an
email notification when being added as a collaborator. This option is only
available to enterprise administrators.

The `canViewPath` parameter allows the invitee to see the entire list of ancestor
folders of the associated file. The user will not gain privileges in any ancestor
folder, but will be able to see the whole path to that file in the owner's account.

The `expiresAt` parameter allows the owner to set a date-time in the future when
the collaboration should expire.

The `isAccessOnly` parameter allows the owner to set the collaboration to be
access only collaboration.

The `notify`, `canViewPath`, `expiresAt` and `isAccessOnly` parameters can be left as `null`.

[collaborate]: https://box.github.io/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#collaborate-java.lang.String-com.box.sdk.BoxCollaboration.Role-
[collaborate2]: https://box.github.io/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#collaborate-com.box.sdk.BoxCollaborator-com.box.sdk.BoxCollaboration.Role-
[collaborate3]: https://box.github.io/box-java-sdk/javadoc/com/box/sdk/BoxFolder.html#collaborate-com.box.sdk.BoxCollaborator-com.box.sdk.BoxCollaboration.Role-java.lang.Boolean-java.lang.Boolean-java.util.Date-java.lang.Boolean-

Get All Collaborations for a Folder
-----------------------------------
Expand Down
32 changes: 30 additions & 2 deletions src/intTest/java/com/box/sdk/BoxCollaborationIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static com.box.sdk.BoxApiProvider.jwtApiForServiceAccount;
import static com.box.sdk.BoxCollaborationAllowlist.AllowlistDirection.INBOUND;
import static com.box.sdk.CleanupTools.deleteFile;
import static com.box.sdk.CleanupTools.deleteFolder;
import static com.box.sdk.UniqueTestFolder.getUniqueFolder;
import static com.box.sdk.UniqueTestFolder.removeUniqueFolder;
Expand All @@ -12,7 +11,10 @@
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.eclipsesource.json.JsonObject;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
Expand Down Expand Up @@ -47,6 +49,7 @@ public void updateInfoSucceeds() {
BoxCollaboration.Info collabInfo = folder.collaborate(collaboratorLogin, originalRole);

assertThat(collabInfo.getRole(), is(equalTo(originalRole)));
assertNotNull(collabInfo.getIsAccessOnly());

BoxCollaboration collab = collabInfo.getResource();
collabInfo.setRole(newRole);
Expand Down Expand Up @@ -149,7 +152,7 @@ public void singleFileCollabSucceeds() {

assertEquals(2, numCollabs);
} finally {
deleteFile(uploadedFile);
CleanupTools.deleteFile(uploadedFile);
if (allowList != null) {
allowList.delete();
}
Expand All @@ -167,4 +170,29 @@ public void acceptPendingCollaboration() {
}
}

@Test
public void singleFileCollabWithAccessOnlySucceeds() {
HashMap<String, BoxCollaboration.Info> collabsMap = new HashMap<>();
BoxAPIConnection api = jwtApiForServiceAccount();
String fileName = "[singleFileCollabSucceeds] Test File.txt";
BoxFile uploadedFile = null;
try {
uploadedFile = uploadFileToUniqueFolderWithSomeContent(api, fileName);
JsonObject user = new JsonObject()
.add("login", TestConfig.getCollaborator())
.add("type", "user");
JsonObject file = new JsonObject()
.add("id", uploadedFile.getID())
.add("type", "file");

BoxCollaboration.Role originalRole = BoxCollaboration.Role.VIEWER;
BoxCollaboration.Info collabInfo = BoxCollaboration.create(api, user, file, originalRole,
false, false, null, true);

assertThat(collabInfo.getRole(), is(equalTo(originalRole)));
assertTrue(collabInfo.getIsAccessOnly());
} finally {
CleanupTools.deleteFile(uploadedFile);
}
}
}
49 changes: 47 additions & 2 deletions src/main/java/com/box/sdk/BoxCollaboration.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class BoxCollaboration extends BoxResource {
*/
public static final String[] ALL_FIELDS = {"type", "id", "item", "accessible_by", "role", "expires_at",
"can_view_path", "status", "acknowledged_at", "created_by",
"created_at", "modified_at"};
"created_at", "modified_at", "is_access_only"};

/**
* Collaborations URL Template.
Expand Down Expand Up @@ -67,7 +67,7 @@ public BoxCollaboration(BoxAPIConnection api, String id) {
*/
protected static BoxCollaboration.Info create(BoxAPIConnection api, JsonObject accessibleBy, JsonObject item,
BoxCollaboration.Role role, Boolean notify, Boolean canViewPath) {
return create(api, accessibleBy, item, role, notify, canViewPath, null);
return create(api, accessibleBy, item, role, notify, canViewPath, null, null);
}

/**
Expand All @@ -91,6 +91,32 @@ protected static BoxCollaboration.Info create(
Boolean canViewPath,
Date expiresAt
) {
return create(api, accessibleBy, item, role, notify, canViewPath, expiresAt, null);
}

/**
* Create a new collaboration object.
*
* @param api the API connection used to make the request.
* @param accessibleBy the JSON object describing who should be collaborated.
* @param item the JSON object describing which item to collaborate.
* @param role the role to give the collaborators.
* @param notify the user/group should receive email notification of the collaboration or not.
* @param canViewPath the view path collaboration feature is enabled or not.
* @param expiresAt the date the collaboration expires
* @param isAccessOnly the collaboration is an access only collaboration or not.
* @return info about the new collaboration.
*/
protected static BoxCollaboration.Info create(
BoxAPIConnection api,
JsonObject accessibleBy,
JsonObject item,
BoxCollaboration.Role role,
Boolean notify,
Boolean canViewPath,
Date expiresAt,
Boolean isAccessOnly
) {

String queryString = "";
if (notify != null) {
Expand All @@ -113,6 +139,9 @@ protected static BoxCollaboration.Info create(
if (expiresAt != null) {
requestJSON.add("expires_at", BoxDateFormat.format(expiresAt));
}
if (isAccessOnly != null) {
requestJSON.add("is_access_only", isAccessOnly);
}

BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");

Expand Down Expand Up @@ -364,6 +393,7 @@ public class Info extends BoxResource.Info {
private BoxItem.Info item;
private String inviteEmail;
private boolean canViewPath;
private boolean isAccessOnly;

/**
* Constructs an empty Info object.
Expand Down Expand Up @@ -453,6 +483,18 @@ public void setCanViewPath(boolean canViewState) {
this.addPendingChange("can_view_path", canViewState);
}

/**
* Gets a boolean indicator weather "is access only" feature is enabled or not. This field is read only.
* It is used to indicate whether a collaboration is an Access Only Collaboration (AOC).
* When set to true, it separates access from interest by hiding collaborated items from the All Files page
* and the ALF stream.
* This means that users who have been granted access through AOCs will not see these items in their
* regular file view.
*/
public boolean getIsAccessOnly() {
return this.isAccessOnly;
}

/**
* The email address used to invite an un-registered collaborator, if they are not a registered user.
*
Expand Down Expand Up @@ -583,6 +625,9 @@ protected void parseJSONMember(JsonObject.Member member) {
case "can_view_path":
this.canViewPath = value.asBoolean();
break;
case "is_access_only":
this.isAccessOnly = value.asBoolean();
break;
case "invite_email":
this.inviteEmail = value.asString();
break;
Expand Down
49 changes: 43 additions & 6 deletions src/main/java/com/box/sdk/BoxFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -1389,13 +1389,15 @@ public BoxFile.Info uploadLargeFile(InputStream inputStream, long fileSize,
}

private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxCollaboration.Role role,
Boolean notify, Boolean canViewPath) {
Boolean notify, Boolean canViewPath, Date expiresAt,
Boolean isAccessOnly) {

JsonObject itemField = new JsonObject();
itemField.add("id", this.getID());
itemField.add("type", "file");

return BoxCollaboration.create(this.getAPI(), accessibleByField, itemField, role, notify, canViewPath);
return BoxCollaboration.create(this.getAPI(), accessibleByField, itemField, role, notify, canViewPath,
expiresAt, isAccessOnly);
}

/**
Expand All @@ -1405,10 +1407,13 @@ private BoxCollaboration.Info collaborate(JsonObject accessibleByField, BoxColla
* @param role the role of the collaborator.
* @param notify determines if the user (or all the users in the group) will receive email notifications.
* @param canViewPath whether view path collaboration feature is enabled or not.
* @param expiresAt when the collaboration should expire.
* @param isAccessOnly whether the collaboration is access only or not.
* @return info about the new collaboration.
*/
public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role,
Boolean notify, Boolean canViewPath) {
Boolean notify, Boolean canViewPath,
Date expiresAt, Boolean isAccessOnly) {
JsonObject accessibleByField = new JsonObject();
accessibleByField.add("id", collaborator.getID());

Expand All @@ -1419,7 +1424,21 @@ public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollab
} else {
throw new IllegalArgumentException("The given collaborator is of an unknown type.");
}
return this.collaborate(accessibleByField, role, notify, canViewPath);
return this.collaborate(accessibleByField, role, notify, canViewPath, expiresAt, isAccessOnly);
}

/**
* Adds a collaborator to this file.
*
* @param collaborator the collaborator to add.
* @param role the role of the collaborator.
* @param notify determines if the user (or all the users in the group) will receive email notifications.
* @param canViewPath whether view path collaboration feature is enabled or not.
* @return info about the new collaboration.
*/
public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollaboration.Role role,
Boolean notify, Boolean canViewPath) {
return this.collaborate(collaborator, role, notify, canViewPath, null, null);
}

/**
Expand All @@ -1430,15 +1449,33 @@ public BoxCollaboration.Info collaborate(BoxCollaborator collaborator, BoxCollab
* @param role the role of the collaborator.
* @param notify determines if the user (or all the users in the group) will receive email notifications.
* @param canViewPath whether view path collaboration feature is enabled or not.
* @param expiresAt when the collaboration should expire.
* @param isAccessOnly whether the collaboration is access only or not.
* @return info about the new collaboration.
*/
public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role,
Boolean notify, Boolean canViewPath) {
Boolean notify, Boolean canViewPath,
Date expiresAt, Boolean isAccessOnly) {
JsonObject accessibleByField = new JsonObject();
accessibleByField.add("login", email);
accessibleByField.add("type", "user");

return this.collaborate(accessibleByField, role, notify, canViewPath);
return this.collaborate(accessibleByField, role, notify, canViewPath, expiresAt, isAccessOnly);
}

/**
* Adds a collaborator to this folder. An email will be sent to the collaborator if they don't already have a Box
* account.
*
* @param email the email address of the collaborator to add.
* @param role the role of the collaborator.
* @param notify determines if the user (or all the users in the group) will receive email notifications.
* @param canViewPath whether view path collaboration feature is enabled or not.
* @return info about the new collaboration.
*/
public BoxCollaboration.Info collaborate(String email, BoxCollaboration.Role role,
Boolean notify, Boolean canViewPath) {
return this.collaborate(email, role, notify, canViewPath, null, null);
}

/**
Expand Down
Loading
Loading