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 grant_user_permission(self, userId, permissionId, format="json", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) try: userId = strip_tags(userId) permission = session.query(Permission).filter( Permission.id == permissionId).one() try: flUser = session.query(User).filter(User.id == userId).one() flUser.permissions.append(permission) session.commit() sMessages.append("User %s granted permission %s" % (userId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("User with ID: %s does not exist" % str(userId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error( "[%s] [grant_user_permission] [Problem granting user a permission: %s]" % (user.id, str(e))) fMessages.append("Problem granting a user permission: %s" % str(e))
def update_user(self, userId, quota=None, email=None, firstName=None, lastName=None, password=None, confirmPassword=None, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: userId = strip_tags(userId) if userId == user.id or AccountService.user_has_permission(user, "admin"): updateUser = AccountService.get_user(userId) #This kind of implicitly enforces permissions updateUser.email = strip_tags(email) if strip_tags(email) is not None else updateUser.email updateUser.quota = int(strip_tags(quota)) if strip_tags(quota) is not None else updateUser.quota updateUser.first_name = strip_tags(firstName) if strip_tags(firstName) is not None else updateUser.first_name updateUser.last_name = strip_tags(lastName) if strip_tags(lastName) is not None else updateUser.last_name if password != "" and password is not None and confirmPassword != "" and confirmPassword is not None: if password == confirmPassword: updateUser.set_password(password) else: fMessages.append("Passwords do not match, password has not been reset") sMessages.append("Successfully updated user settings") session.add(AuditLog(user.id, Actions.UPDATE_USER, "%s updated user account \"%s\"" % (user.id, userId), userId)) session.commit() else: fMessages.append("You do not have permission to update this user") except Exception, e: session.rollback() cherrypy.log.error("[%s] [update_user] [Problem rupdating user: %s]" % (user.id, str(e))) fMessages.append("Problem while updating user: %s" % str(e))
def revoke_role_permission(self, roleId, permissionId, format="json", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) try: roleId = strip_tags(roleId) permission = session.query(Permission).filter( Permission.id == permissionId).one() try: role = session.query(Role).filter(Role.id == roleId).one() role.permissions.remove(permission) session.commit() sMessages.append("Role %s no longer has permission %s" % (roleId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Role with ID: %s does not exist" % str(roleId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error( "[%s] [revoke_role_permission] [Problem revoking a role permission: %s]" % (user.id, str(e))) fMessages.append("Problem revoking a role permission: %s" % str(e))
def revoke_user_permission(self, userId, permissionId, format="json", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) try: permission = session.query(Permission).filter( Permission.id == permissionId).one() try: flUser = session.query(User).filter(User.id == userId).one() if flUser.id == user.id and permission.id == "admin": fMessages.append( "You cannot remove admin permissions from your own account" ) else: flUser.permissions.remove(permission) session.commit() sMessages.append("User %s no longer has permission %s" % (userId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("User with ID: %s does not exist" % str(userId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error( "[%s] [revoke_user_permission] [Problem revoking a user permission: %s]" % (user.id, str(e))) fMessages.append("Problem revoking a user permission: %s" % str(e))
def create_role(self, roleId, roleName, email, quota, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: roleId = strip_tags(roleId) existingRole = session.query(Role).filter(Role.id == roleId).scalar() if existingRole is None: roleName = strip_tags(roleName) email = strip_tags(email) quota = int(quota) newRole = Role(id=roleId, name=roleName, email=email, quota=quota) session.add(newRole) session.add(AuditLog(user.id, Actions.CREATE_ROLE, "%s added a role to the system named \"%s\"" % (user.id, newRole.name), None)) session.commit() sMessages.append("Successfully created a role named %s. Other users who are added to this role may act on behalf of this role now." % str(roleName)) else: fMessages.append("A role with role ID: %s already exists" % str(roleId)) except ValueError: fMessages.append("Quota must be a positive integer") except Exception, e: session.rollback() cherrypy.log.error("[%s] [create_role] [Problem creating role: %s]" % (user.id, str(e))) fMessages.append("Problem creating role: %s" % str(e))
def remove_users_from_group(self, userIds, groupId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: userIds = split_list_sanitized(userIds) groupId = int(strip_tags(groupId)) group = session.query(Group).filter(Group.id==groupId).one() if group.owner_id == user.id or AccountService.user_has_permission(user, "admin"): for userId in userIds: user = AccountService.get_user(userId) group.members.remove(user) session.add(AuditLog(user.id, Actions.UPDATE_GROUP, "%s user(s) removed from group \"%s\"(%s)" % (len(userIds), group.name, group.id))) session.commit() sMessages.append("Group members removed successfully") else: fMessages.append("You do not have permission to modify group with ID:%s" % str(groupId)) except ValueError: fMessages.append("Invalid group Id") except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Group with ID:%s could not be found" % str(groupId)) except Exception, e: session.rollback() fMessages.append("Couldn't remove members from group: %s" % str(e)) cherrypy.log.error("[%s] [remove_users_from_group] [Couldn't remove members from group: %s]" % (user.id, str(e)))
def update_server_config(self, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: for key in kwargs: if key.startswith("config_name_"): parameterName = key[12:] # Parameter description should not be updated by client #description = kwargs['config_desc_%s' % parameterName] value = None if parameterName.endswith("pass"): #Don't strip characters from passwords value = kwargs[key] else: value = strip_tags(kwargs[key]) parameter = session.query(ConfigParameter).filter(ConfigParameter.name == parameterName).one() # Parameter description should not be updated by client #parameter.description = description parameter.value = value session.commit() #TODO: Make sure this if phased out properly #Filelocker.update_config(cherrypy.request.app.config) except Exception, e: session.rollback() cherrypy.log.error("[%s] [update_server_config] [Could not update server config: %s]" % (user.id, str(e))) fMessages.append("Unable to update config: %s" % str(e))
def update_role(self, roleId, roleName, email, quota, format="json", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) try: roleId = strip_tags(roleId) existingRole = session.query(Role).filter(Role.id == roleId).one() existingRole.name = strip_tags(roleName) existingRole.email = strip_tags(email) existingRole.quota = int(quota) session.add( AuditLog( user.id, Actions.UPDATE_ROLE, "%s updated role \"%s\"(%s)" % (user.id, existingRole.name, existingRole.id), None, existingRole.id)) session.commit() sMessages.append("Successfully updated a role named %s." % str(roleName)) except ValueError: fMessages.append("Quota must be a positive integer") except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Role with ID:%s could not be found to update." % str(roleId)) except Exception, e: session.rollback() cherrypy.log.error( "[%s] [update_role] [Problem creating role: %s]" % (user.id, str(e))) fMessages.append("Problem creating role: %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 update_server_config(self, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: for key in kwargs: if key.startswith("config_name_"): parameterName = key[12:] # Parameter description should not be updated by client #description = kwargs['config_desc_%s' % parameterName] value = None if parameterName.endswith( "pass" ): #Don't strip characters from passwords value = kwargs[key] else: value = strip_tags(kwargs[key]) parameter = session.query(ConfigParameter).filter( ConfigParameter.name == parameterName).one() # Parameter description should not be updated by client #parameter.description = description parameter.value = value session.commit() #TODO: Make sure this if phased out properly #Filelocker.update_config(cherrypy.request.app.config) except Exception, e: session.rollback() cherrypy.log.error( "[%s] [update_server_config] [Could not update server config: %s]" % (user.id, str(e))) fMessages.append("Unable to update config: %s" % str(e))
def delete_user_shares(self, fileIds, userId, format="json"): user, role, sMessages, fMessages = ( cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], []) fileIds = split_list_sanitized(fileIds) for fileId in fileIds: try: flFile = session.query(File).filter(File.id == fileId).one() if ( role is not None and flFile.role_owner_id == role.id ) or flFile.owner_id == user.id or AccountService.user_has_permission( user, "admin"): ps = session.query(UserShare).filter( and_(UserShare.user_id == userId, UserShare.file_id == flFile.id)).scalar() if ps is not None: session.delete(ps) session.add( AuditLog( user.id, Actions.DELETE_USER_SHARE, "You stopped sharing file %s with %s" % (flFile.name, userId), None, role.id if role is not None else None)) session.commit() sMessages.append("Share has been successfully deleted") else: fMessages.append("This share does not exist") else: fMessages.append( "You do not have permission to modify shares for file with ID: %s" % str(flFile.id)) except Exception, e: session.rollback() fMessages.append("Problem deleting share for file: %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 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 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 create_clikey(self, hostIPv4, hostIPv6, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: if self.validIPv4.match(hostIPv4): hostIPv6 = '' elif self.validIPv6.match(hostIPv6): hostIPv4 = '' else: fMessages.append("No IP address specified.") return fl_response(sMessages, fMessages, format) CLIkeyGen = str(os.urandom(32).encode('hex'))[0:32] try: existingKey = session.query(CLIKey).filter(CLIKey.user_id==user.id).filter(CLIKey.host_ipv4==hostIPv4).filter(CLIKey.host_ipv6==hostIPv6).one() existingKey.value=CLIkeyGen session.add(AuditLog(user.id, Actions.UPDATE_CLIKEY, "%s updated CLI Key for host: %s%s" % (user.id, hostIPv4, hostIPv6))) session.commit() sMessages.append("Successfully updated key for host: %s%s." % (str(hostIPv4),str(hostIPv6))) except sqlalchemy.orm.exc.NoResultFound, nrf: newKey = CLIKey(user_id=strip_tags(user.id), host_ipv4=strip_tags(hostIPv4), host_ipv6=strip_tags(hostIPv6), value=CLIkeyGen) session.add(newKey) session.add(AuditLog(user.id, Actions.CREATE_CLIKEY, "%s created CLI Key for host: %s%s" % (user.id, hostIPv4, hostIPv6))) session.commit() sMessages.append("Successfully added key for host: %s%s." % (str(hostIPv4),str(hostIPv6))) except Exception, e: session.rollback() cherrypy.log.error("[%s] [create_clikey] [Problem creating key: %s]" % (user.id, str(e))) fMessages.append("Problem creating key: %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 queue_for_deletion(filePath): try: if session.query(DeletedFile).filter(DeletedFile.file_name==filePath).scalar() is None: session.add(DeletedFile(file_name=filePath)) session.commit() except Exception, e: cherrypy.log.error("Unable to queue file for deletion: %s" % str(e)) session.rollback()
def create_group_shares(self, fileIds, groupId, notify="false", cc="false", format="json", requestOrigin=""): user, role, sMessages, fMessages, config = (cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], [], cherrypy.request.app.config['filelocker']) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: orgConfig = get_config_dict_from_objects(session.query(ConfigParameter).filter(ConfigParameter.name.like('org_%')).all()) fileIds = split_list_sanitized(fileIds) groupId = strip_tags(groupId) if groupId is not None and groupId != "" else None notify = True if notify.lower() == "true" else False cc = True if cc.lower() == "true" else False try: if groupId is not None: sharedFiles = [] group = session.query(Group).filter(Group.id==groupId).one() if (role is not None and group.role_owner_id == role.id) or group.owner_id == user.id or AccountService.user_has_permission(user, "admin"): for fileId in fileIds: flFile = session.query(File).filter(File.id == fileId).one() existingShare = session.query(GroupShare).filter(and_(GroupShare.group_id==group.id, GroupShare.file_id==fileId)).scalar() if existingShare is not None: fMessages.append("File %s is already shared with group %s" % (flFile.name, group.name)) elif (role is not None and flFile.role_owner_id == role.id) or flFile.owner_id == user.id or AccountService.user_has_permission(user, "admin"): flFile.group_shares.append(GroupShare(group_id=groupId, file_id=fileId)) sharedFiles.append(flFile) else: fMessages.append("You do not have permission to share file with ID: %s" % fileId) sMessages.append("Shared file(s) successfully") if role is not None: session.add(AuditLog(user.id, Actions.CREATE_GROUP_SHARE, "Role %s shared %s files with group %s(%s)" % (role.id, len(fileIds), group.name, group.id), None, role.id)) else: session.add(AuditLog(user.id, Actions.CREATE_GROUP_SHARE, "%s shared %s files with group %s(%s)" % (user.id, len(fileIds), group.name, group.id), None)) else: fMessages.append("You do not have permission to share with this group") session.commit() if notify: cherrypy.session.release_lock() for groupMember in group.members: try: Mail.notify(get_template_file('share_notification.tmpl'),{'sender':user.email if role is None else role.email,'recipient':groupMember.email, 'ownerId':user.id if role is None else role.id, 'ownerName':user.display_name if role is None else role.name, 'sharedFiles':sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name']}) session.add(AuditLog(user.id, Actions.SEND_EMAIL, "%s has been notified via email that you have shared a file with him or her." % (groupMember.email), None, role.id if role is not None else None)) session.commit() except Exception, e: session.rollback() fMessages.append("Problem sending email notification to %s: %s" % (groupMember.display_name, str(e))) if cc: if (user.email is not None and user.email != ""): try: Mail.notify(get_template_file('share_notification.tmpl'),{'sender':user.email if role is None else role.email,'recipient':user.email if role is None else role.email, 'ownerId':user.id if role is None else role.id, 'ownerName':user.display_name if role is None else role.name, 'sharedFiles':sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name']}) session.add(AuditLog(user.id, Actions.SEND_EMAIL, "You have been carbon copied via email on the notification that was sent out as a result of your file share.")) session.commit() except Exception, e: session.rollback() fMessages.append("Problem carbon copying email notification: %s" % (str(e))) else: fMessages.append("You elected to receive a carbon copy of the share notification, however your account does not have an email address set.")
def cluster_elections(config): try: currentNodeId = int(config["filelocker"]["cluster_member_id"]) currentNode = session.query(ClusterNode).filter(ClusterNode.member_id == currentNodeId).scalar() if currentNode is None: # This node isn't in the DB yet, check in import socket currentNode = ClusterNode( member_id=currentNodeId, hostname=socket.gethostname(), is_master=False, last_seen_timestamp=datetime.datetime.now(), ) session.add(currentNode) session.commit() else: # In the DB, update last seen to avoid purging currentNode.last_seen_timestamp = datetime.datetime.now() session.commit() currentMaster = session.query(ClusterNode).filter(ClusterNode.is_master == True).scalar() # If this is default master node and another node has assumed master, reset and force election if currentNodeId == 0 and currentNode.is_master == False and currentMaster is not None: for node in session.query(ClusterNode).all(): node.is_master = False session.commit() # This isn't the default master, there is one, but it's expired elif currentMaster is not None and currentMaster.last_seen_timestamp < datetime.datetime.now() - datetime.timedelta( minutes=5 ): # master is expired session.delete(currentMaster) session.commit() # No master, hold election elif currentMaster is None: # No master nodes found, become master if eligible purge_expired_nodes() highestPriority = currentNode.member_id for node in session.query(ClusterNode).all(): if node.member_id < highestPriority: highestPriority = node.member_id break if ( highestPriority == currentNode.member_id ): # Current node has lowest node id, thus highest priority, assume master currentNode.is_master = True session.commit() return True except sqlalchemy.orm.exc.ConcurrentModificationError, cme: cherrypy.log.error( "[system] [cluster_elections] [Concurrency error during elections. This can occur if locks on the DB inhibit normal cluster elections. If this error occurs infrequently, it can usually be disregarded. Full Error: %s]" % str(cme) ) session.rollback() return False
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 create_user_shares(self, fileIds, userId=None, notify="no", cc="false", format="json", requestOrigin="", **kwargs): config = cherrypy.request.app.config['filelocker'] orgConfig = get_config_dict_from_objects(session.query(ConfigParameter).filter(ConfigParameter.name.like('org_%')).all()) 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) userId = strip_tags(userId) if userId is not None and userId != "" else None notify = True if notify.lower() == "true" else False cc = True if cc.lower() == "true" else False sharedFiles, recipients = [], [] try: if userId is not None: shareUser = AccountService.get_user(userId) if (shareUser.email is not None and shareUser.email != ""): recipients.append(shareUser) for fileId in fileIds: flFile = session.query(File).filter(File.id==fileId).one() if (role is not None and flFile.role_owner_id == role.id) or flFile.owner_id == user.id or AccountService.user_has_permission(user, "admin"): existingShare = session.query(UserShare).filter(and_(UserShare.file_id==fileId, UserShare.user_id==userId)).scalar() if existingShare is None: flFile.user_shares.append(UserShare(user_id=userId, file_id=fileId)) session.commit() sharedFiles.append(flFile) if role is not None: session.add(AuditLog(user.id, Actions.CREATE_USER_SHARE, "Role %s shared file %s(%s) with %s" % (role.id, flFile.name, flFile.id, shareUser.id), shareUser.id, role.id)) else: session.add(AuditLog(user.id, "Create User Share", "%s shared file %s(%s) with %s" % (user.id, flFile.name, flFile.id, shareUser.id), shareUser.id)) session.commit() else: fMessages.append("You do not have permission to share file with ID: %s" % str(flFile.id)) if notify: cherrypy.session.release_lock() if cc: if (user is not None and user != ""): recipients.append(user) else: fMessages.append("You elected to receive a carbon copy of the share notification, however your account does not have an email address set.") for recipient in recipients: try: Mail.notify(get_template_file('share_notification.tmpl'),{'sender':user.email if role is None else role.email,'recipient':recipient.email, 'ownerId':user.id if role is None else role.id, 'ownerName':user.display_name if role is None else role.name, 'sharedFiles':sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name'], 'personalMessage': ""}) session.add(AuditLog(user.id, Actions.SEND_EMAIL, "%s(%s) has been notified via email that you have shared a file with him or her." % (recipient.display_name, recipient.id), None, role.id if role is not None else None)) except Exception, e: session.rollback() fMessages.append("Problem sending email notification to %s: %s" % (recipient.display_name, str(e))) session.commit() sMessages.append("Shared file(s) successfully") else: fMessages.append("You did not specify a user to share the file with")
def cluster_elections(config): try: currentNodeId = int(config['filelocker']['cluster_member_id']) currentNode = session.query(ClusterNode).filter( ClusterNode.member_id == currentNodeId).scalar() if currentNode is None: #This node isn't in the DB yet, check in import socket currentNode = ClusterNode( member_id=currentNodeId, hostname=socket.gethostname(), is_master=False, last_seen_timestamp=datetime.datetime.now()) session.add(currentNode) session.commit() else: #In the DB, update last seen to avoid purging currentNode.last_seen_timestamp = datetime.datetime.now() session.commit() currentMaster = session.query(ClusterNode).filter( ClusterNode.is_master == True).scalar() #If this is default master node and another node has assumed master, reset and force election if currentNodeId == 0 and currentNode.is_master == False and currentMaster is not None: for node in session.query(ClusterNode).all(): node.is_master = False session.commit() #This isn't the default master, there is one, but it's expired elif currentMaster is not None and currentMaster.last_seen_timestamp < datetime.datetime.now( ) - datetime.timedelta(minutes=5): #master is expired session.delete(currentMaster) session.commit() #No master, hold election elif currentMaster is None: #No master nodes found, become master if eligible purge_expired_nodes() highestPriority = currentNode.member_id for node in session.query(ClusterNode).all(): if node.member_id < highestPriority: highestPriority = node.member_id break if highestPriority == currentNode.member_id: #Current node has lowest node id, thus highest priority, assume master currentNode.is_master = True session.commit() return True except sqlalchemy.orm.exc.ConcurrentModificationError, cme: cherrypy.log.error( "[system] [cluster_elections] [Concurrency error during elections. This can occur if locks on the DB inhibit normal cluster elections. If this error occurs infrequently, it can usually be disregarded. Full Error: %s]" % str(cme)) session.rollback() return False
def delete_clikey(self, hostIPv4, hostIPv6, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: clikey = session.query(CLIKey).filter(CLIKey.host_ipv4==hostIPv4).filter(CLIKey.host_ipv6==hostIPv6).one() if clikey.user_id == user.id or AccountService.user_has_permission(user, "admin"): session.delete(clikey) sMessages.append("Key %s deleted successfully" % clikey.value) session.add(AuditLog(user.id, Actions.DELETE_CLIKEY, "%s deleted CLI Key for host: %s%s" % (user.id, hostIPv4, hostIPv6))) except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find key for host: %s%s" % str(hostIPv4), str(hostIPv6)) session.commit() except Exception, e: session.rollback() fMessages.append("Could not delete Key: %s" % str(e)) cherrypy.log.error("[%s] [delete_clikey] [Could not delete key: %s]" % (user.id, str(e)))
def delete_group_shares(self, fileIds, groupId, format="json"): user, role, sMessages, fMessages = ( cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], []) fileIds = split_list_sanitized(fileIds) for fileId in fileIds: try: group = session.query(Group).filter(Group.id == groupId).one() if ( role is not None and group.role_owner_id == role.id ) or group.owner_id == user.id or AccountService.user_has_permission( user, "admin"): flFile = session.query(File).filter( File.id == fileId).one() if ( role is not None and flFile.role_owner_id == role.id ) or flFile.owner_id == user.id or AccountService.user_has_permission( user, "admin"): share = session.query(GroupShare).filter( GroupShare.group_id == groupId and GroupShare.file_id == flFile.id).scalar() if share is not None: session.delete(share) session.add( AuditLog( user.id, Actions.DELETE_GROUP_SHARE, "You stopped sharing file %s with group %s" % (flFile.name, group.name), None, role.id if role is not None else None)) session.commit() else: fMessages.append( "You do not have permission to modify shares for file with ID: %s" % str(flFile.id)) else: fMessages.append( "You do not have permission delete shares with this group" ) except Exception, e: session.rollback() fMessages.append("Problem deleting share for file: %s" % 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 create_attribute(self, attributeName, attributeId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: attributeName, attributeId = strip_tags(attributeName), strip_tags(attributeId) if attributeId is None: fMessages.append("You must specify an ID for an attribute") elif attributeName is None: fMessages.append("You must give this attribute a name") else: attribute = Attribute(name=attributeName, id=attributeId) session.add(attribute) session.commit() sMessages.append("Successfully created a new attribute") except Exception, e: session.rollback() cherrypy.log.error("[%s] [create_attribute] [Could not create attribute: %s]" % (user.id, str(e))) fMessages.append("Unable to create attribute: %s" % str(e))
def grant_user_permission(self, userId, permissionId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: userId = strip_tags(userId) permission = session.query(Permission).filter(Permission.id == permissionId).one() try: flUser = session.query(User).filter(User.id == userId).one() flUser.permissions.append(permission) session.commit() sMessages.append("User %s granted permission %s" % (userId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("User with ID: %s does not exist" % str(userId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [grant_user_permission] [Problem granting user a permission: %s]" % (user.id, str(e))) fMessages.append("Problem granting a user permission: %s" % str(e))
def grant_role_permission(self, roleId, permissionId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: roleId = strip_tags(roleId) permission = session.query(Permission).filter(Permission.id == permissionId).one() try: role = session.query(Role).filter(Role.id == roleId).one() role.permissions.append(permission) session.commit() sMessages.append("Role %s granted permission %s" % (roleId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Role with ID: %s does not exist" % str(roleId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [grant_role_permission] [Problem granting role a permission: %s]" % (user.id, str(e))) fMessages.append("Problem granting a role permission: %s" % str(e))
def revoke_role_permission(self, roleId, permissionId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: roleId = strip_tags(roleId) permission = session.query(Permission).filter(Permission.id == permissionId).one() try: role = session.query(Role).filter(Role.id == roleId).one() role.permissions.remove(permission) session.commit() sMessages.append("Role %s no longer has permission %s" % (roleId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Role with ID: %s does not exist" % str(roleId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [revoke_role_permission] [Problem revoking a role permission: %s]" % (user.id, str(e))) fMessages.append("Problem revoking a role permission: %s" % str(e))
def delete_groups(self, groupIds, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: groupIds = split_list_sanitized(groupIds) for groupId in groupIds: try: group = session.query(Group).filter(Group.id==groupId).one() if group.owner_id == user.id or AccountService.user_has_permission(user, "admin"): session.delete(group) sMessages.append("Group %s deleted successfully" % group.name) session.add(AuditLog(user.id, Actions.DELETE_GROUP, "%s deleted group \"%s\"(%s)" % (user.id, group.name, group.id), None)) except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find group with ID: %s" % str(groupId)) session.commit() except Exception, e: session.rollback() fMessages.append("Could not delete groups: %s" % str(e)) cherrypy.log.error("[%s] [remove_users_from_group] [Could not delete groups: %s]" % (user.id, str(e)))
def update_group(self, groupId, groupName=None, groupScope="private", format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: groupId = strip_tags(groupId) group = session.query(Group).filter(Group.id == groupId).one() if group.owner_id == user.id or AccountService.user_has_permission(user, "admin"): group.name = strip_tags(groupName) if strip_tags(groupName) is not None else group.name group.scope = strip_tags(groupScope.lower()) if groupScope is not None else group.scope session.add(AuditLog(user.id, Actions.UPDATE_GROUP, "Group \"%s\"(%s) has been updated" % (group.name, group.id))) session.commit() sMessages.append("Group updated") else: fMessages.append("You do not have permission to update this group") except sqlalchemy.orm.exc.NoResultFound, nrf: fMessages.append("Could not find group with ID: %s" % str(groupId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [update_group] [Couldn't update group: %s]" % (user.id, str(e))) fMessages.append("Could not update group: %s" % str(e))
def update_role(self, roleId, roleName, email, quota, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: roleId = strip_tags(roleId) existingRole = session.query(Role).filter(Role.id == roleId).one() existingRole.name = strip_tags(roleName) existingRole.email = strip_tags(email) existingRole.quota = int(quota) session.add(AuditLog(user.id, Actions.UPDATE_ROLE, "%s updated role \"%s\"(%s)" % (user.id, existingRole.name, existingRole.id), None, existingRole.id)) session.commit() sMessages.append("Successfully updated a role named %s." % str(roleName)) except ValueError: fMessages.append("Quota must be a positive integer") except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Role with ID:%s could not be found to update." % str(roleId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [update_role] [Problem creating role: %s]" % (user.id, str(e))) fMessages.append("Problem creating role: %s" % str(e))
def create_group(self, groupName, groupMemberIds=None, groupScope="private", format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: scope = strip_tags(groupScope.lower()) if strip_tags(groupScope) is not None else "private" group = Group(name=strip_tags(groupName), scope=scope, owner_id=user.id) session.add(group) memberIds = split_list_sanitized(groupMemberIds) for memberId in memberIds: try: member = session.query(User).filter(User.id==memberId).one() group.members.append(member) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Could not find user with id:\"%s\" to add to group" % str(memberId)) session.add(AuditLog(user.id, Actions.CREATE_GROUP, "%s created a group named \"%s\"(%s)" % (user.id, group.name, group.id), None)) session.commit() except Exception, e: session.rollback() fMessages.append("Could not create group: %s" % str(e)) cherrypy.log.error("[%s] [create_group] [Couldn't create group: %s]" % (user.id, str(e)))
def revoke_user_permission(self, userId, permissionId, format="json", requestOrigin="", **kwargs): user, sMessages, fMessages = (cherrypy.session.get("user"), [], []) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: try: permission = session.query(Permission).filter(Permission.id == permissionId).one() try: flUser = session.query(User).filter(User.id == userId).one() if flUser.id == user.id and permission.id == "admin": fMessages.append("You cannot remove admin permissions from your own account") else: flUser.permissions.remove(permission) session.commit() sMessages.append("User %s no longer has permission %s" % (userId, permissionId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("User with ID: %s does not exist" % str(userId)) except sqlalchemy.orm.exc.NoResultFound: fMessages.append("Permission with ID: %s does not exist" % str(permissionId)) except Exception, e: session.rollback() cherrypy.log.error("[%s] [revoke_user_permission] [Problem revoking a user permission: %s]" % (user.id, str(e))) fMessages.append("Problem revoking a user permission: %s" % str(e))
def delete_user_shares(self, fileIds, userId, format="json", requestOrigin=""): 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: flFile = session.query(File).filter(File.id==fileId).one() if (role is not None and flFile.role_owner_id == role.id) or flFile.owner_id == user.id or AccountService.user_has_permission(user, "admin"): ps = session.query(UserShare).filter(and_(UserShare.user_id == userId, UserShare.file_id == flFile.id)).scalar() if ps is not None: session.delete(ps) session.add(AuditLog(user.id, Actions.DELETE_USER_SHARE, "You stopped sharing file %s with %s" % (flFile.name, userId), None, role.id if role is not None else None)) session.commit() sMessages.append("Share has been successfully deleted") else: fMessages.append("This share does not exist") else: fMessages.append("You do not have permission to modify shares for file with ID: %s" % str(flFile.id)) except Exception, e: session.rollback() fMessages.append("Problem deleting share for file: %s" % str(e))
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))
def delete_group_shares(self, fileIds, groupId, format="json", requestOrigin=""): 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: group = session.query(Group).filter(Group.id==groupId).one() if (role is not None and group.role_owner_id == role.id) or group.owner_id == user.id or AccountService.user_has_permission(user, "admin"): flFile = session.query(File).filter(File.id==fileId).one() if (role is not None and flFile.role_owner_id == role.id) or flFile.owner_id == user.id or AccountService.user_has_permission(user, "admin"): share = session.query(GroupShare).filter(GroupShare.group_id == groupId and GroupShare.file_id == flFile.id).scalar() if share is not None: session.delete(share) session.add(AuditLog(user.id, Actions.DELETE_GROUP_SHARE, "You stopped sharing file %s with group %s" % (flFile.name, group.name), None, role.id if role is not None else None)) session.commit() else: fMessages.append("You do not have permission to modify shares for file with ID: %s" % str(flFile.id)) else: fMessages.append("You do not have permission delete shares with this group") except Exception, e: session.rollback() fMessages.append("Problem deleting share for file: %s" % str(e))
def create_public_share(self, fileIds, expiration, shareType, message, notifyEmails, cc="false", format="json", requestOrigin="", **kwargs): user, role, sMessages, fMessages, shareId, ps = (cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], [], None, None) if requestOrigin != cherrypy.session['request-origin']: fMessages.append("Missing request key!!") else: config = cherrypy.request.app.config['filelocker'] orgConfig = get_config_dict_from_objects(session.query(ConfigParameter).filter(ConfigParameter.name.like('org_%')).all()) fileIds = split_list_sanitized(fileIds) cc = True if cc == "true" else False try: try: expiration = datetime.datetime(*(time.strptime(strip_tags(expiration), "%m/%d/%Y")[0:6])) except Exception, e: raise Exception("Invalid expiration date format. Date must be in mm/dd/yyyy format.") if expiration is None or expiration == "": raise Exception("Public shares must have a valid expiration date") message = strip_tags(message) shareType = "single" if shareType != "multi" else "multi" ps = PublicShare(date_expires=expiration, reuse=shareType, message=message) if role is not None: ps.role_owner_id = role.id else: ps.owner_id = user.id if (kwargs.has_key("password") and kwargs['password']!=""): ps.set_password(kwargs['password']) elif shareType=="multi": raise Exception("You must specify a password for public shares that don't expire after 1 use") ps.generate_share_id() session.add(ps) sharedFiles = [] for fileId in fileIds: flFile = session.query(File).filter(File.id==fileId).one() if flFile.owner_id == user.id or AccountService.user_has_permission(user, "admin"): ps.files.append(flFile) session.commit() sharedFiles.append(flFile) session.commit() else: fMessages.append("You do not have permission to share file with ID: %s" % str(flFile.id)) session.add(AuditLog(user.id, Actions.CREATE_PUBLIC_SHARE, "%s file(s) publicly shared." % len(ps.files), None, role.id if role is not None else None)) notifyEmailList = split_list_sanitized(notifyEmails) if cc: if (user.email is not None and user.email != ""): notifyEmailList.append(user.email) else: fMessages.append("You elected to receive a carbon copy of the share notification, however your account does not have an email address set.") cherrypy.session.release_lock() for recipient in notifyEmailList: if recipient is not None and recipient != "": Mail.notify(get_template_file('public_share_notification.tmpl'), {'sender':user.email if role is None else role.email, 'recipient':recipient, 'sharedFiles':sharedFiles, 'ownerId':user.id if role is None else role.id, 'ownerName': user.display_name if role is None else role.name, 'shareId':ps.id, 'filelockerURL':config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name'], 'personalMessage': message}) if len(notifyEmailList) > 0: session.add(AuditLog(user.id, Actions.SEND_EMAIL, "Email notifications about a public share were sent to the following addresses: %s" % ",".join(notifyEmailList), None, role.id if role is not None else None)) session.commit() shareId = ps.id sMessages.append("Files shared successfully") except Exception, e: session.rollback() fMessages.append(str(e)) cherrypy.log.error("[%s] [create_public_share] [Unable to create public share: %s]" % (user.id, str(e)))
except Exception, e: session.rollback() fMessages.append("Problem sending email notification to %s: %s" % (groupMember.display_name, str(e))) if cc: if (user.email is not None and user.email != ""): try: Mail.notify(get_template_file('share_notification.tmpl'),{'sender':user.email if role is None else role.email,'recipient':user.email if role is None else role.email, 'ownerId':user.id if role is None else role.id, 'ownerName':user.display_name if role is None else role.name, 'sharedFiles':sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name']}) session.add(AuditLog(user.id, Actions.SEND_EMAIL, "You have been carbon copied via email on the notification that was sent out as a result of your file share.")) session.commit() except Exception, e: session.rollback() fMessages.append("Problem carbon copying email notification: %s" % (str(e))) else: fMessages.append("You elected to receive a carbon copy of the share notification, however your account does not have an email address set.") except Exception, e: session.rollback() fMessages.append(str(e)) return fl_response(sMessages, fMessages, format) @cherrypy.expose @cherrypy.tools.requires_login() def delete_group_shares(self, fileIds, groupId, format="json", requestOrigin=""): 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: group = session.query(Group).filter(Group.id==groupId).one() if (role is not None and group.role_owner_id == role.id) or group.owner_id == user.id or AccountService.user_has_permission(user, "admin"):
def create_group_shares(self, fileIds, groupId, notify="false", cc="false", format="json"): user, role, sMessages, fMessages, config = ( cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], [], cherrypy.request.app.config['filelocker']) orgConfig = get_config_dict_from_objects( session.query(ConfigParameter).filter( ConfigParameter.name.like('org_%')).all()) fileIds = split_list_sanitized(fileIds) groupId = strip_tags( groupId) if groupId is not None and groupId != "" else None notify = True if notify.lower() == "true" else False cc = True if cc.lower() == "true" else False try: if groupId is not None: sharedFiles = [] group = session.query(Group).filter(Group.id == groupId).one() if ( role is not None and group.role_owner_id == role.id ) or group.owner_id == user.id or AccountService.user_has_permission( user, "admin"): for fileId in fileIds: flFile = session.query(File).filter( File.id == fileId).one() existingShare = session.query(GroupShare).filter( and_(GroupShare.group_id == group.id, GroupShare.file_id == fileId)).scalar() if existingShare is not None: fMessages.append( "File %s is already shared with group %s" % (flFile.name, group.name)) elif ( role is not None and flFile.role_owner_id == role.id ) or flFile.owner_id == user.id or AccountService.user_has_permission( user, "admin"): flFile.group_shares.append( GroupShare(group_id=groupId, file_id=fileId)) sharedFiles.append(flFile) else: fMessages.append( "You do not have permission to share file with ID: %s" % fileId) sMessages.append("Shared file(s) successfully") if role is not None: session.add( AuditLog( user.id, Actions.CREATE_GROUP_SHARE, "Role %s shared %s files with group %s(%s)" % (role.id, len(fileIds), group.name, group.id), None, role.id)) else: session.add( AuditLog( user.id, Actions.CREATE_GROUP_SHARE, "%s shared %s files with group %s(%s)" % (user.id, len(fileIds), group.name, group.id), None)) else: fMessages.append( "You do not have permission to share with this group") session.commit() if notify: cherrypy.session.release_lock() for groupMember in group.members: try: Mail.notify( get_template_file('share_notification.tmpl'), { 'sender': user.email if role is None else role.email, 'recipient': groupMember.email, 'ownerId': user.id if role is None else role.id, 'ownerName': user.display_name if role is None else role.name, 'sharedFiles': sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name'] }) session.add( AuditLog( user.id, Actions.SEND_EMAIL, "%s has been notified via email that you have shared a file with him or her." % (groupMember.email), None, role.id if role is not None else None)) session.commit() except Exception, e: session.rollback() fMessages.append( "Problem sending email notification to %s: %s" % (groupMember.display_name, str(e))) if cc: if (user.email is not None and user.email != ""): try: Mail.notify( get_template_file( 'share_notification.tmpl'), { 'sender': user.email if role is None else role.email, 'recipient': user.email if role is None else role.email, 'ownerId': user.id if role is None else role.id, 'ownerName': user.display_name if role is None else role.name, 'sharedFiles': sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name'] }) session.add( AuditLog( user.id, Actions.SEND_EMAIL, "You have been carbon copied via email on the notification that was sent out as a result of your file share." )) session.commit() except Exception, e: session.rollback() fMessages.append( "Problem carbon copying email notification: %s" % (str(e))) else: fMessages.append( "You elected to receive a carbon copy of the share notification, however your account does not have an email address set." )
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)) return fl_response(sMessages, fMessages, format) @cherrypy.expose @cherrypy.tools.requires_login() def delete_files(self, fileIds, format="json", **kwargs): user, role, sMessages, fMessages = ( cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], []) 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:
def create_user_shares(self, fileIds, userId=None, notify="no", cc="false", format="json", **kwargs): config = cherrypy.request.app.config['filelocker'] orgConfig = get_config_dict_from_objects( session.query(ConfigParameter).filter( ConfigParameter.name.like('org_%')).all()) user, role, sMessages, fMessages = ( cherrypy.session.get("user"), cherrypy.session.get("current_role"), [], []) fileIds = split_list_sanitized(fileIds) userId = strip_tags( userId) if userId is not None and userId != "" else None notify = True if notify.lower() == "true" else False cc = True if cc.lower() == "true" else False sharedFiles, recipients = [], [] try: if userId is not None: shareUser = AccountService.get_user(userId) if (shareUser.email is not None and shareUser.email != ""): recipients.append(shareUser) for fileId in fileIds: flFile = session.query(File).filter( File.id == fileId).one() if ( role is not None and flFile.role_owner_id == role.id ) or flFile.owner_id == user.id or AccountService.user_has_permission( user, "admin"): existingShare = session.query(UserShare).filter( and_(UserShare.file_id == fileId, UserShare.user_id == userId)).scalar() if existingShare is None: flFile.user_shares.append( UserShare(user_id=userId, file_id=fileId)) session.commit() sharedFiles.append(flFile) if role is not None: session.add( AuditLog( user.id, Actions.CREATE_USER_SHARE, "Role %s shared file %s(%s) with %s" % (role.id, flFile.name, flFile.id, shareUser.id), shareUser.id, role.id)) else: session.add( AuditLog( user.id, "Create User Share", "%s shared file %s(%s) with %s" % (user.id, flFile.name, flFile.id, shareUser.id), shareUser.id)) session.commit() else: fMessages.append( "You do not have permission to share file with ID: %s" % str(flFile.id)) if notify: cherrypy.session.release_lock() if cc: if (user is not None and user != ""): recipients.append(user) else: fMessages.append( "You elected to receive a carbon copy of the share notification, however your account does not have an email address set." ) for recipient in recipients: try: Mail.notify( get_template_file('share_notification.tmpl'), { 'sender': user.email if role is None else role.email, 'recipient': recipient.email, 'ownerId': user.id if role is None else role.id, 'ownerName': user.display_name if role is None else role.name, 'sharedFiles': sharedFiles, 'filelockerURL': config['root_url'], 'org_url': orgConfig['org_url'], 'org_name': orgConfig['org_name'], 'personalMessage': "" }) session.add( AuditLog( user.id, Actions.SEND_EMAIL, "%s(%s) has been notified via email that you have shared a file with him or her." % (recipient.display_name, recipient.id), None, role.id if role is not None else None)) except Exception, e: session.rollback() fMessages.append( "Problem sending email notification to %s: %s" % (recipient.display_name, str(e))) session.commit() sMessages.append("Shared file(s) successfully") else: