Skip to content

Commit

Permalink
feat: Support access only collaboration (#1193)
Browse files Browse the repository at this point in the history
* feat: Support access only collaboration
  • Loading branch information
congminh1254 authored Aug 11, 2023
1 parent be875e8 commit 664c01f
Show file tree
Hide file tree
Showing 15 changed files with 271 additions and 37 deletions.
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

0 comments on commit 664c01f

Please sign in to comment.