summaryrefslogtreecommitdiffstats
path: root/idrop-web/grails-app/controllers/org/irods/mydrop/controller/SharingController.groovy
blob: 1a21c3ea1093cd7364bd1d0daf29d18552856d70 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
package org.irods.mydrop.controller


import grails.converters.JSON

import org.irods.jargon.core.connection.IRODSAccount
import org.irods.jargon.core.exception.JargonException
import org.irods.jargon.core.exception.JargonRuntimeException
import org.irods.jargon.core.protovalues.FilePermissionEnum
import org.irods.jargon.core.pub.CollectionAO
import org.irods.jargon.core.pub.CollectionAndDataObjectListAndSearchAO
import org.irods.jargon.core.pub.DataObjectAO
import org.irods.jargon.core.pub.IRODSAccessObjectFactory
import org.irods.jargon.core.pub.UserAO
import org.irods.jargon.core.pub.domain.DataObject
import org.springframework.security.core.context.SecurityContextHolder


class SharingController {

	IRODSAccessObjectFactory irodsAccessObjectFactory
	IRODSAccount irodsAccount

	/**
	 * Interceptor grabs IRODSAccount from the SecurityContextHolder
	 */
	def beforeInterceptor = {
		def irodsAuthentication = SecurityContextHolder.getContext().authentication

		if (irodsAuthentication == null) {
			throw new JargonRuntimeException("no irodsAuthentication in security context!")
		}

		irodsAccount = irodsAuthentication.irodsAccount
		log.debug("retrieved account for request: ${irodsAccount}")
	}

	def afterInterceptor = {
		log.debug("closing the session")
		irodsAccessObjectFactory.closeSession()
	}


	def listAcl = {

		def absPath = params['absPath']
		if (absPath == null) {
			throw new JargonException("no absolute path passed to the method")
		}

		log.info("listAcl for absPath: ${absPath}")
		def acls;

		try {

			CollectionAndDataObjectListAndSearchAO collectionAndDataObjectListAndSearchAO = irodsAccessObjectFactory.getCollectionAndDataObjectListAndSearchAO(irodsAccount)

			def retObj = collectionAndDataObjectListAndSearchAO.getFullObjectForType(absPath)

			def isDataObject = retObj instanceof DataObject


			if (isDataObject) {
				log.debug("retrieving ACLs for a data object");
				DataObjectAO dataObjectAO = irodsAccessObjectFactory.getDataObjectAO(irodsAccount)
				acls = dataObjectAO.listPermissionsForDataObject(retObj.collectionName + "/" + retObj.dataName)
			} else {
				log.debug("retrieveing ACLs for collection")
				CollectionAO collectionAO = irodsAccessObjectFactory.getCollectionAO(irodsAccount)
				acls = collectionAO.listPermissionsForCollection(retObj.collectionName)
			}
		} catch (Exception je){
			log.error("exception getting acl data ${je}", je)
			flash.message = "Unable to find ACL data"
		}

		render(view:"aclDetails", model:[acls:acls])
	}
	
	/**
	 * Display an Acl dialog for an add or edit
	 */
	def prepareAclDialog = {
		log.info "prepareAclDialog"
		log.info "params: ${params}"
			
		// if a user is provided, this will be an edit, otherwise, it's a create
		def userName = params['userName']
		def absPath = params['absPath']
		def isCreate = params['create']
		
		
		if (!absPath) {
			log.error "no absPath in request for prepareAclDialog()"
			throw new JargonException("a path was not supplied")
		}
		
		
		render(view:"aclDialog", model:[absPath:absPath, userName:userName, userPermissionEnum:FilePermissionEnum.listAllValues(), isCreate:isCreate])
		
	}
	
	/**
	 * Update the ACL by responding to an AJAX editable update on a node. This uses the editable feature of the
	 * ACL JQuery table
	 */
	def updateAcl = {
		log.info "updating ACL"
		log.info "params: ${params}"
		def userName = params['userName']
		def acl = params['acl']
		def absPath = params['absPath']
		def isCreate = params['create']


		if (!userName) {
			throw new JargonException("userName not supplied")
		}

		if (!acl) {
			throw new JargonException("acl not supplied")
		}

		if (!absPath) {
			throw new JargonException("absPath not supplied")
		}
		
		if (!isCreate) {
			isCreate = true
		}

		log.info("updateACL userName: ${userName} acl: ${acl} absPath: ${absPath}")

		CollectionAndDataObjectListAndSearchAO collectionAndDataObjectListAndSearchAO = irodsAccessObjectFactory.getCollectionAndDataObjectListAndSearchAO(irodsAccount)

		def retObj = collectionAndDataObjectListAndSearchAO.getFullObjectForType(absPath)
		
		def isDataObject = retObj instanceof DataObject

		// FIXME: add this into the file object superclass in jargon-core

		if (isDataObject) {
			log.debug("setting ACLs for a data object")
			DataObjectAO dataObjectAO = irodsAccessObjectFactory.getDataObjectAO(irodsAccount)
			
			// if creating a new ACL, an ACL cannot already exist
			
			if (isCreate) {
				def existingPermission = dataObjectAO.getPermissionForDataObjectForUserName(absPath, userName)
				if (existingPermission) {
					response.sendError(500,"The given user already has a sharing permission")
					return
				}
			}

			if (acl == "READ") {
				dataObjectAO.setAccessPermissionRead(irodsAccount.getZone(), absPath, userName)
			} else if (acl == "WRITE") {
				dataObjectAO.setAccessPermissionWrite(irodsAccount.getZone(), absPath, userName)
			} else if (acl == "OWN") {
				dataObjectAO.setAccessPermissionOwn(irodsAccount.getZone(), absPath, userName)
			} else {
				throw new JargonException("Unknown acl value ${acl}")
			}
		} else {
			log.debug("setting ACLs for collection")
			CollectionAO collectionAO = irodsAccessObjectFactory.getCollectionAO(irodsAccount)
			
			if (isCreate) {
				def existingPermission = collectionAO.getPermissionForUserName(absPath, userName)
				if (existingPermission) {
					response.sendError(500,"The given user already has a sharing permission")
					return
				}
			}
			  
			if (acl == "READ") {
				collectionAO.setAccessPermissionRead(irodsAccount.getZone(), absPath, userName, true)
			} else if (acl == "WRITE") {
				collectionAO.setAccessPermissionWrite(irodsAccount.getZone(), absPath, userName, true)
			} else if (acl == "OWN") {
				collectionAO.setAccessPermissionOwn(irodsAccount.getZone(), absPath, userName, true)
			} else {
				throw new JargonException("Unknown acl value ${acl}")
			}
		}

		log.info("acl set successfully")

		render "OK"
	}
	
	/**
	 * List the users in iRODS based on user name.  A 'term' parameter may be supplied, in which case, a LIKE% query will be used to find
	 * matching user names.  This method returns JSON as expected for the JQuery UI autocomplete text box
	 */
	def listUsersForAutocomplete = {
		
		log.info("listUsersForAutocomplete")
		def term = params['term']
		if (!term) {
			term = ""
		}		
		log.info("term:${term}")
		
		UserAO userAO = irodsAccessObjectFactory.getUserAO(irodsAccount)
		
		def userList = userAO.findUserNameLike(term);
		def jsonBuff = []
		
		
		userList.each {
			jsonBuff.add(
				["label": it]
				)
		}
		
		render jsonBuff as JSON
	
	}
	
	def deleteAcl = {
		log.info("deleteAcl")
		log.info(params)
		render "hello"
		
	}
}