def delete_users(self, userIds, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: userIds = split_list_sanitized(userIds) try: for userId in userIds: try: delUser = session.query(User).filter(User.id == userId).one() session.delete(delUser) for flFile in session.query(File).filter(File.owner_id == delUser.id): FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add(AuditLog(user.id, Actions.DELETE_FILE, "File %s (%s) owned by user %s has been deleted as a result of the owner being deleted. " % (flFile.name, flFile.id, delUser.id), "admin")) session.add(AuditLog(user.id, Actions.DELETE_USER, "User with ID: \"%s\" deleted from system" % delUser.id, "admin")) sMessages.append("Successfully deleted user %s" % userId) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("User with ID:%s does not exist" % userId) except Exception, e: fMessages.append("Could not delete user: %s" % str(e)) session.commit() except Exception, e: session.rollback() cherrypy.log.error("[%s] [delete_users] [Could not delete users: %s]" % (user.id, str(e))) fMessages.append("Could not delete users: %s" % str(e))
def delete_roles(self, roleIds, format="json", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) try: roleIds = split_list_sanitized(roleIds) for roleId in roleIds: try: role = session.query(Role).filter(Role.id == roleId).one() session.delete(role) for flFile in session.query(File).filter( File.role_owner_id == role.id): FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add( AuditLog( user.id, Actions.DELETE_FILE, "File %s (%s) owned by role %s has been deleted as a result of the role owner being deleted. " % (flFile.name, flFile.id, role.id), "admin")) session.add( AuditLog( user.id, Actions.DELETE_ROLE, "%s deleted role \"%s\"(%s) from the system" % (user.id, role.name, role.id), None)) sMessages.append("Successfully deleted roles%s." % str(roleId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("The role ID: %s does not exist" % str(roleId)) session.commit() except Exception, e: session.rollback() cherrypy.log.error( "[%s] [delete_roles] [Problem deleting roles: %s]" % (user.id, str(e))) fMessages.append("Problem deleting roles: %s" % str(e))
def enc_file_generator(self, user, decrypter, dFile, fileId=None, publicShareId=None): endOfFile = False readData = dFile.read(1024*8) data = decrypter.decrypt(readData) #If the data is less than one block long, just process it and send it out #try: if len(data) < (1024*8): padding = int(str(data[-1:]),16) #A 0 represents that the file had a multiple of 16 bytes, and 16 bytes of padding were added if padding==0: padding=16 endOfFile = True FileService.file_download_complete(user, fileId, publicShareId) yield data[:len(data)-padding] else: #For multiblock files while True: if endOfFile: FileService.file_download_complete(user, fileId, publicShareId) break next_data = decrypter.decrypt(dFile.read(1024*8)) if (next_data is not None and next_data != "") and not len(next_data)<(1024*8): yData = data data = next_data yield yData #This prevents padding going across block boundaries by aggregating the last two blocks and processing #as a whole if the next block is less than a full block (signifying end of file) else: data = data + next_data padding = int(str(data[-1:]),16) #A 0 represents that the file had a multiple of 16 bytes, and 16 bytes of padding were added if padding==0: padding=16 endOfFile = True yield data[:len(data)-padding]
def routine_maintenance(config): from lib import AccountService expiredFiles = session.query(File).filter( File.date_expires < datetime.datetime.now()) for flFile in expiredFiles: try: for share in flFile.user_shares: session.delete(share) for share in flFile.group_shares: session.delete(share) for share in flFile.public_shares: session.delete(share) for share in flFile.attribute_shares: session.delete(share) FileService.queue_for_deletion(flFile.id) session.add( AuditLog( "admin", Actions.DELETE_FILE, "File %s (ID:%s) has expired and has been purged by the system." % (flFile.name, flFile.id), flFile.owner_id)) session.delete(flFile) session.commit() except Exception, e: session.rollback() cherrypy.log.error( "[system] [routine_maintenance] [Error while deleting expired file: %s]" % str(e))
def delete_files(self, fileIds, format="json", requestOrigin="", **kwargs): user, role, sMessages, fMessages = (cherrypy.session.get("user"),cherrypy.session.get("current_role"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: fileIds = split_list_sanitized(fileIds) for fileId in fileIds: try: fileId = int(fileId) flFile = session.query(File).filter(File.id == fileId).one() if flFile.role_owner_id is not None and role is not None and flFile.role_owner_id == role.id: FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add(AuditLog(user.id, Actions.DELETE_FILE, "File %s (%s) owned by role %s has been deleted by user %s. " % (flFile.name, flFile.id, role.name, user.id))) session.commit() sMessages.append("File %s deleted successfully" % flFile.name) elif flFile.owner_id == user.id or AccountService.user_has_permission(user, "admin"): FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add(AuditLog(user.id, Actions.DELETE_FILE, "File %s (%s) has been deleted" % (flFile.name, flFile.id))) session.commit() sMessages.append("File %s deleted successfully" % flFile.name) else: fMessages.append("You do not have permission to delete file %s" % flFile.name) except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find file with ID: %s" % str(fileId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [delete_files] [Could not delete file: %s]" % (user.id, str(e))) fMessages.append("File not deleted: %s" % str(e))
def routine_maintenance(config): from lib import AccountService expiredFiles = session.query(File).filter(File.date_expires < datetime.datetime.now()) for flFile in expiredFiles: try: for share in flFile.user_shares: session.delete(share) for share in flFile.group_shares: session.delete(share) for share in flFile.public_shares: session.delete(share) for share in flFile.attribute_shares: session.delete(share) FileService.queue_for_deletion(flFile.id) session.add( AuditLog( "admin", Actions.DELETE_FILE, "File %s (ID:%s) has expired and has been purged by the system." % (flFile.name, flFile.id), flFile.owner_id, ) ) session.delete(flFile) session.commit() except Exception, e: session.rollback() cherrypy.log.error("[system] [routine_maintenance] [Error while deleting expired file: %s]" % str(e))
def clean_temp_files(config): # Cleanup orphaned temp files, possibly resulting from stalled transfers validTempFiles = [] for key in cherrypy.file_uploads.keys(): for progressFile in cherrypy.file_uploads[key]: validTempFiles.append(progressFile.file_object.name.split(os.path.sep)[-1]) FileService.clean_temp_files(config, validTempFiles)
def clean_temp_files(config): #Cleanup orphaned temp files, possibly resulting from stalled transfers validTempFiles = [] for key in cherrypy.file_uploads.keys(): for progressFile in cherrypy.file_uploads[key]: validTempFiles.append( progressFile.file_object.name.split(os.path.sep)[-1]) FileService.clean_temp_files(config, validTempFiles)
def get_quota_usage(self, format="json", **kwargs): user, sMessages, fMessages, quotaMB, quotaUsedMB = (cherrypy.session.get("user"),[], [], 0, 0) try: quotaMB, quotaUsage = 0,0 if cherrypy.session.get("current_role") is not None: quotaMB = cherrypy.session.get("current_role").quota quotaUsage = FileService.get_role_quota_usage_bytes(cherrypy.session.get("current_role").id) else: quotaMB = user.quota quotaUsage = FileService.get_user_quota_usage_bytes(user.id) quotaUsedMB = int(quotaUsage) / 1024 / 1024 except Exception, e: fMessages.append(str(e))
def delete_files(self, fileIds, format="json", requestOrigin="", **kwargs): user, role, sMessages, fMessages = ( cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: fileIds = split_list_sanitized(fileIds) for fileId in fileIds: try: fileId = int(fileId) flFile = session.query(File).filter( File.id == fileId).one() if flFile.role_owner_id is not None and role is not None and flFile.role_owner_id == role.id: FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add( AuditLog( user.id, Actions.DELETE_FILE, "File %s (%s) owned by role %s has been deleted by user %s. " % (flFile.name, flFile.id, role.name, user.id))) session.commit() sMessages.append("File %s deleted successfully" % flFile.name) elif flFile.owner_id == user.id or AccountService.user_has_permission( user, "admin"): FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add( AuditLog( user.id, Actions.DELETE_FILE, "File %s (%s) has been deleted" % (flFile.name, flFile.id))) session.commit() sMessages.append("File %s deleted successfully" % flFile.name) else: fMessages.append( "You do not have permission to delete file %s" % flFile.name) except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find file with ID: %s" % str(fileId)) except Exception, e: session.rollback() cherrypy.log.error( "[%s] [delete_files] [Could not delete file: %s]" % (user.id, str(e))) fMessages.append("File not deleted: %s" % str(e))
def get_quota_usage(self, format="json", **kwargs): user, sMessages, fMessages, quotaMB, quotaUsedMB = ( cherrypy.session.get("user"), [], [], 0, 0) try: quotaMB, quotaUsage = 0, 0 if cherrypy.session.get("current_role") is not None: quotaMB = cherrypy.session.get("current_role").quota quotaUsage = FileService.get_role_quota_usage_bytes( cherrypy.session.get("current_role").id) else: quotaMB = user.quota quotaUsage = FileService.get_user_quota_usage_bytes(user.id) quotaUsedMB = int(quotaUsage) / 1024 / 1024 except Exception, e: fMessages.append(str(e))
def take_file(self, fileId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: config = cherrypy.request.app.config['filelocker'] try: flFile = session.query(File).filter(File.id==fileId).one() if flFile.owner_id == user.id: fMessages.append("You cannot take your own file") elif flFile.shared_with(user) or AccountService.user_has_permission(user, "admin"): if (FileService.get_user_quota_usage_bytes(user) + flFile.size) >= (user.quota*1024*1024): cherrypy.log.error("[%s] [take_file] [User has insufficient quota space remaining to check in file: %s]" % (user.id, flFile.name)) raise Exception("You may not copy this file because doing so would exceed your quota") takenFile = flFile.get_copy() takenFile.owner_id = user.id takenFile.date_uploaded = datetime.datetime.now() takenFile.notify_on_download = False session.add(takenFile) session.commit() shutil.copy(os.path.join(config['vault'],str(flFile.id)), os.path.join(config['vault'],str(takenFile.id))) sMessages.append("Successfully took ownership of file %s. This file can now be shared with other users just as if you had uploaded it. " % flFile.name) else: fMessages.append("You do not have permission to take this file") except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find file with ID: %s" % str(fileId)) except Exception, e: session.rollback() fMessages.append(str(e))
def take_file(self, fileId, format="json", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) config = cherrypy.request.app.config['filelocker'] try: flFile = session.query(File).filter(File.id == fileId).one() if flFile.owner_id == user.id: fMessages.append("You cannot take your own file") elif flFile.shared_with( user) or AccountService.user_has_permission(user, "admin"): if (FileService.get_user_quota_usage_bytes(user) + flFile.size) >= (user.quota * 1024 * 1024): cherrypy.log.error( "[%s] [take_file] [User has insufficient quota space remaining to check in file: %s]" % (user.id, flFile.name)) raise Exception( "You may not copy this file because doing so would exceed your quota" ) takenFile = flFile.get_copy() takenFile.owner_id = user.id takenFile.date_uploaded = datetime.datetime.now() takenFile.notify_on_download = False session.add(takenFile) session.commit() shutil.copy(os.path.join(config['vault'], str(flFile.id)), os.path.join(config['vault'], str(takenFile.id))) sMessages.append( "Successfully took ownership of file %s. This file can now be shared with other users just as if you had uploaded it. " % flFile.name) else: fMessages.append( "You do not have permission to take this file") except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find file with ID: %s" % str(fileId))
def get_vault_usage(self, format="json", **kwargs): user, sMessages, fMessages, vaultUsedMB, vaultCapacityMB = (cherrypy.session.get("user"), [], [], 0, 0) try: vaultSpaceFreeMB, vaultCapacityMB = FileService.get_vault_usage() vaultUsedMB = vaultCapacityMB - vaultSpaceFreeMB except Exception, e: cherrypy.log.error("[%s] [get_vault_usage] [Error while getting quota: %s]" % (user.id,str(e))) fMessages.append("Could not get vault usage: %s" % str(e))
def enc_file_generator(self, user, decrypter, dFile, fileId=None, publicShareId=None): endOfFile = False readData = dFile.read(1024 * 8) data = decrypter.decrypt(readData) #If the data is less than one block long, just process it and send it out #try: if len(data) < (1024 * 8): padding = int(str(data[-1:]), 16) #A 0 represents that the file had a multiple of 16 bytes, and 16 bytes of padding were added if padding == 0: padding = 16 endOfFile = True FileService.file_download_complete(user, fileId, publicShareId) yield data[:len(data) - padding] else: #For multiblock files while True: if endOfFile: FileService.file_download_complete(user, fileId, publicShareId) break next_data = decrypter.decrypt(dFile.read(1024 * 8)) if (next_data is not None and next_data != "") and not len(next_data) < (1024 * 8): yData = data data = next_data yield yData #This prevents padding going across block boundaries by aggregating the last two blocks and processing #as a whole if the next block is less than a full block (signifying end of file) else: data = data + next_data padding = int(str(data[-1:]), 16) #A 0 represents that the file had a multiple of 16 bytes, and 16 bytes of padding were added if padding == 0: padding = 16 endOfFile = True yield data[:len(data) - padding]
def delete_roles(self, roleIds, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: roleIds = split_list_sanitized(roleIds) for roleId in roleIds: try: role = session.query(Role).filter(Role.id == roleId).one() session.delete(role) for flFile in session.query(File).filter(File.role_owner_id == role.id): FileService.queue_for_deletion(flFile.id) session.delete(flFile) session.add(AuditLog(user.id, Actions.DELETE_FILE, "File %s (%s) owned by role %s has been deleted as a result of the role owner being deleted. " % (flFile.name, flFile.id, role.id), "admin")) session.add(AuditLog(user.id, Actions.DELETE_ROLE, "%s deleted role \"%s\"(%s) from the system" % (user.id, role.name, role.id), None)) sMessages.append("Successfully deleted roles%s." % str(roleId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("The role ID: %s does not exist" % str(roleId)) session.commit() except Exception, e: session.rollback() cherrypy.log.error("[%s] [delete_roles] [Problem deleting roles: %s]" % (user.id, str(e))) fMessages.append("Problem deleting roles: %s" % str(e))
"admin", Actions.DELETE_FILE, "File %s (ID:%s) has expired and has been purged by the system." % (flFile.name, flFile.id), flFile.owner_id, ) ) session.delete(flFile) session.commit() except Exception, e: session.rollback() cherrypy.log.error("[system] [routine_maintenance] [Error while deleting expired file: %s]" % str(e)) expiredMessages = session.query(Message).filter(Message.date_expires < datetime.datetime.now()) for message in expiredMessages: try: session.delete(message) FileService.queue_for_deletion("m%s" % str(message.id)) session.add( AuditLog( "admin", Actions.DELETE_MESSAGE, "Message %s (ID:%s) has expired and has been deleted by the system." % (message.messageSubject, message.messageId), message.owner_id, ) ) session.commit() except Exception, e: session.rollback() cherrypy.log.error("[system] [routine_maintenance] [Error while deleting expired message: %s]" % str(e)) expiredUploadRequests = session.query(UploadRequest).filter(UploadRequest.date_expires < datetime.datetime.now()) for uploadRequest in expiredUploadRequests:
user, sMessages, fMessages = cherrypy.session.get("user"), cherrypy.session.get("sMessages"), cherrypy.session.get("fMessages") uploadKey = user.id if cherrypy.session.get("current_role") is not None: role = cherrypy.session.get("current_role") #Check upload size lcHDRS = {} for key, val in cherrypy.request.headers.iteritems(): lcHDRS[key.lower()] = val try: fileSizeBytes = int(lcHDRS['content-length']) except KeyError, ke: fMessages.append("Request must have a valid content length") raise cherrypy.HTTPError(411, "Request must have a valid content length") fileSizeMB = ((fileSizeBytes/1024)/1024) vaultSpaceFreeMB, vaultCapacityMB = FileService.get_vault_usage() if (fileSizeMB*2) >= vaultSpaceFreeMB: cherrypy.log.error("[system] [upload] [File vault is running out of space and cannot fit this file. Remaining Space is %s MB, fileSizeBytes is %s]" % (vaultSpaceFreeMB, fileSizeBytes)) fMessages.append("The server doesn't have enough space left on its drive to fit this file. The administrator has been notified.") raise cherrypy.HTTPError(413, "The server doesn't have enough space left on its drive to fit this file. The administrator has been notified.") quotaSpaceRemainingBytes = 0 if role is not None: quotaSpaceRemainingBytes = (role.quota*1024*1024) - FileService.get_role_quota_usage_bytes(role.id) else: quotaSpaceRemainingBytes = (user.quota*1024*1024) - FileService.get_user_quota_usage_bytes(user.id) if fileSizeBytes > quotaSpaceRemainingBytes: fMessages.append("File size is larger than your quota will accommodate") raise cherrypy.HTTPError(413, "File size is larger than your quota will accommodate") #The server won't respond to additional user requests (polling) until we release the lock
uploadKey = user.id if cherrypy.session.get("current_role") is not None: role = cherrypy.session.get("current_role") #Check upload size lcHDRS = {} for key, val in cherrypy.request.headers.iteritems(): lcHDRS[key.lower()] = val try: fileSizeBytes = int(lcHDRS['content-length']) except KeyError, ke: fMessages.append("Request must have a valid content length") raise cherrypy.HTTPError( 411, "Request must have a valid content length") fileSizeMB = ((fileSizeBytes / 1024) / 1024) vaultSpaceFreeMB, vaultCapacityMB = FileService.get_vault_usage() if (fileSizeMB * 2) >= vaultSpaceFreeMB: cherrypy.log.error( "[system] [upload] [File vault is running out of space and cannot fit this file. Remaining Space is %s MB, fileSizeBytes is %s]" % (vaultSpaceFreeMB, fileSizeBytes)) fMessages.append( "The server doesn't have enough space left on its drive to fit this file. The administrator has been notified." ) raise cherrypy.HTTPError( 413, "The server doesn't have enough space left on its drive to fit this file. The administrator has been notified." ) quotaSpaceRemainingBytes = 0 if role is not None: quotaSpaceRemainingBytes = (
"admin", Actions.DELETE_FILE, "File %s (ID:%s) has expired and has been purged by the system." % (flFile.name, flFile.id), flFile.owner_id)) session.delete(flFile) session.commit() except Exception, e: session.rollback() cherrypy.log.error( "[system] [routine_maintenance] [Error while deleting expired file: %s]" % str(e)) expiredMessages = session.query(Message).filter( Message.date_expires < datetime.datetime.now()) for message in expiredMessages: try: session.delete(message) FileService.queue_for_deletion("m%s" % str(message.id)) session.add( AuditLog( "admin", Actions.DELETE_MESSAGE, "Message %s (ID:%s) has expired and has been deleted by the system." % (message.messageSubject, message.messageId), message.owner_id)) session.commit() except Exception, e: session.rollback() cherrypy.log.error( "[system] [routine_maintenance] [Error while deleting expired message: %s]" % str(e)) expiredUploadRequests = session.query(UploadRequest).filter( UploadRequest.date_expires < datetime.datetime.now()) for uploadRequest in expiredUploadRequests: