001/* 002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * vpasquier <vpasquier@nuxeo.com> 016 */ 017package org.nuxeo.box.api.collaboration; 018 019import org.apache.commons.lang.RandomStringUtils; 020import org.nuxeo.box.api.adapter.BoxAdapter; 021import org.nuxeo.box.api.folder.adapter.BoxFolderAdapter; 022import org.nuxeo.box.api.marshalling.dao.BoxCollaboration; 023import org.nuxeo.box.api.marshalling.dao.BoxUser; 024import org.nuxeo.box.api.marshalling.exceptions.BoxJSONException; 025import org.nuxeo.box.api.marshalling.exceptions.BoxRestException; 026import org.nuxeo.box.api.service.BoxService; 027import org.nuxeo.ecm.core.api.CoreSession; 028import org.nuxeo.ecm.core.api.DocumentModel; 029import org.nuxeo.ecm.core.api.DocumentNotFoundException; 030import org.nuxeo.ecm.core.api.DocumentRef; 031import org.nuxeo.ecm.core.api.IdRef; 032import org.nuxeo.ecm.core.api.NuxeoException; 033import org.nuxeo.ecm.core.api.security.ACE; 034import org.nuxeo.ecm.core.api.security.ACL; 035import org.nuxeo.ecm.core.api.security.ACP; 036import org.nuxeo.ecm.core.api.security.impl.ACLImpl; 037import org.nuxeo.ecm.webengine.WebException; 038import org.nuxeo.ecm.webengine.model.WebObject; 039import org.nuxeo.ecm.webengine.model.impl.AbstractResource; 040import org.nuxeo.ecm.webengine.model.impl.ResourceTypeImpl; 041import org.nuxeo.runtime.api.Framework; 042 043import javax.ws.rs.DELETE; 044import javax.ws.rs.GET; 045import javax.ws.rs.POST; 046import javax.ws.rs.PUT; 047import javax.ws.rs.Path; 048import javax.ws.rs.PathParam; 049import javax.ws.rs.Produces; 050import javax.ws.rs.core.MediaType; 051import javax.ws.rs.core.Response; 052 053/** 054 * WebObject for a Box Collaboration 055 * 056 * @since 5.9.3 057 */ 058@WebObject(type = "collaborations") 059@Produces({ MediaType.APPLICATION_JSON }) 060public class BoxCollaborationObject extends AbstractResource<ResourceTypeImpl> { 061 062 BoxService boxService; 063 064 BoxFolderAdapter boxFolder; 065 066 @Override 067 public void initialize(Object... args) { 068 boxService = Framework.getLocalService(BoxService.class); 069 if (args != null && args.length == 1) { 070 try { 071 String folderId = (String) args[0]; 072 CoreSession session = ctx.getCoreSession(); 073 DocumentModel folder = session.getDocument(new IdRef(folderId)); 074 boxFolder = (BoxFolderAdapter) folder.getAdapter(BoxAdapter.class); 075 } catch (NuxeoException e) { 076 throw WebException.wrap(e); 077 } 078 setRoot(true); 079 } 080 } 081 082 @GET 083 public String doGetCollaborations() throws DocumentNotFoundException, BoxJSONException { 084 return boxService.toJSONString(boxFolder.getCollaborations()); 085 } 086 087 @GET 088 @Path("/{collaborationId}") 089 public String doGetCollaboration(@PathParam("collaborationId") String collaborationId) throws 090 BoxJSONException { 091 CoreSession session = ctx.getCoreSession(); 092 String[] collaborationIds = boxService.getCollaborationArrayIds(collaborationId); 093 DocumentModel folder = session.getDocument(new IdRef(collaborationIds[0])); 094 boxFolder = (BoxFolderAdapter) folder.getAdapter(BoxAdapter.class); 095 BoxCollaboration collaboration = boxFolder.getCollaboration(collaborationIds[1]); 096 if (collaboration == null) { 097 throw new BoxRestException("There is no collaboration with id " + collaborationId, 098 Response.Status.NOT_FOUND.getStatusCode()); 099 } 100 return boxService.toJSONString(collaboration); 101 } 102 103 /** 104 * Delete specific ACL for a given folder id 105 */ 106 @DELETE 107 @Path("/{collaborationId}") 108 public void doRemoveCollaboration(@PathParam("collaborationId") String collaborationId) 109 throws DocumentNotFoundException, BoxJSONException { 110 CoreSession session = ctx.getCoreSession(); 111 String[] collaborationIds = boxService.getCollaborationArrayIds(collaborationId); 112 DocumentRef docRef = new IdRef(collaborationIds[0]); 113 ACP acp = session.getACP(docRef); 114 acp.removeACL(collaborationIds[1]); 115 session.setACP(docRef, acp, true); 116 session.save(); 117 } 118 119 @POST 120 public String doPostCollaboration(String jsonBoxCollaboration) throws BoxJSONException { 121 final CoreSession session = ctx.getCoreSession(); 122 BoxCollaboration boxCollaboration = boxService.getBoxCollaboration(jsonBoxCollaboration); 123 String documentId = boxCollaboration.getFolder().getId(); 124 DocumentModel targetDocument = session.getDocument(new IdRef(documentId)); 125 // ACLs Setup 126 ACP acp = session.getACP(targetDocument.getRef()); 127 String collaborationId = RandomStringUtils.random(6, false, true); 128 ACL acl = acp.getACL(collaborationId); 129 if (acl == null) { 130 acl = new ACLImpl(collaborationId); 131 acp.addACL(acl); 132 } 133 ACE ace = new ACE(boxCollaboration.getAccessibleBy().getId(), boxService.getNxBoxRole().inverse().get( 134 boxCollaboration.getRole()), true); 135 acl.add(ace); 136 session.setACP(targetDocument.getRef(), acp, true); 137 session.save(); 138 // Return the new box collab json 139 BoxFolderAdapter boxFolderUpdated = (BoxFolderAdapter) targetDocument.getAdapter(BoxAdapter.class); 140 return boxService.toJSONString(boxService.getBoxCollaboration(boxFolderUpdated, ace, collaborationId)); 141 } 142 143 @PUT 144 @Path("/{collaborationId}") 145 public String doPutCollaboration(@PathParam("collaborationId") String collaborationId, String jsonBoxCollaboration) 146 throws BoxJSONException { 147 final CoreSession session = ctx.getCoreSession(); 148 BoxCollaboration boxCollaboration = boxService.getBoxCollaboration(jsonBoxCollaboration); 149 String[] collaborationIds = boxService.getCollaborationArrayIds(collaborationId); 150 DocumentRef docRef = new IdRef(collaborationIds[0]); 151 DocumentModel targetDocument = session.getDocument(docRef); 152 // ACLs Setup 153 ACP acp = session.getACP(targetDocument.getRef()); 154 ACL acl = acp.getACL(collaborationIds[1]); 155 if (acl == null) { 156 return null; 157 } 158 159 // Get the changes 160 ACE existingACE = acl.getACEs()[0]; 161 String updatedPermission = boxService.getNxBoxRole().inverse().get(boxCollaboration.getRole()); 162 BoxUser updatedUser = boxCollaboration.getAccessibleBy(); 163 String user = updatedUser != null ? updatedUser.getId() : existingACE.getUsername(); 164 String permission = updatedPermission != null ? updatedPermission : existingACE.getPermission(); 165 // Remove the existing ACE - creating the new one 166 acl.remove(0); 167 ACE ace = new ACE(user, permission, true); 168 acl.add(ace); 169 session.setACP(targetDocument.getRef(), acp, true); 170 session.save(); 171 // Return the new box collab json 172 BoxFolderAdapter boxFolderUpdated = (BoxFolderAdapter) targetDocument.getAdapter(BoxAdapter.class); 173 return boxService.toJSONString(boxService.getBoxCollaboration(boxFolderUpdated, ace, collaborationIds[1])); 174 } 175 176}