Ejemplo n.º 1
0
def ticketGalleryFsView(ticketId, securityCode, fileName):
    """
        View-file-within-a-ticket-generated-gallery-view route.

        Helper endpoint to return viewable (only viewables,
        there's no 'download') files in a ticket-gallery view.
        Must take care of punching the ticket.
    """
    user = g.user
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    #
    richTicket = dbGetEnrichAndCheckTicket(
        db,
        'g',
        ticketId,
        securityCode,
        request.url_root,
    )
    if richTicket is not None:
        issuer = dbGetUser(db, richTicket['ticket'].username)
        if richTicket['redeemable']:
            # valid ticket. Further checks are on the way.
            if (not g.settings['behaviour']['behaviour_tickets']
                ['protect_banned_user_tickets']['value']
                    or issuer.banned == 0):
                #
                boxPath = richTicket['metadata']['box_path']
                request._onErrorUrl = url_for(
                    'lsView',
                    lsPathString='/'.join(boxPath[1:]),
                )
                parentBox = getBoxFromPath(db, boxPath[1:], issuer)
                if parentBox is not None:
                    # we retrieve the file and serve it
                    file = getFileFromParent(db, parentBox, fileName, issuer)
                    if file is not None:
                        dbPunchRichTicket(db, richTicket)
                        filePhysicalPath, filePhysicalName = fileIdToSplitPath(
                            file.file_id,
                            fileStorageDirectory=fileStorageDirectory,
                        )
                        return send_from_directory(
                            filePhysicalPath,
                            filePhysicalName,
                            attachment_filename=file.name,
                            as_attachment=True,
                            mimetype=file.mime_type,
                        )
                    else:
                        return abort(404, 'Content unavailable')
                else:
                    return abort(404, 'Content unavailable')
            else:
                return abort(404, 'Content unavailable')
        else:
            return abort(404, 'Content unavailable')
    else:
        return abort(404, 'Content unavailable')
Ejemplo n.º 2
0
def fsDownloadView(fsPathString=''):
    """Download-file view."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    if parentBox is not None:
        file = getFileFromParent(db, parentBox, fileName, user)
        if file is not None:
            filePhysicalPath, filePhysicalName = fileIdToSplitPath(
                file.file_id,
                fileStorageDirectory=fileStorageDirectory,
            )
            return send_from_directory(
                filePhysicalPath,
                filePhysicalName,
                attachment_filename=file.name,
                as_attachment=True,
                mimetype=file.mime_type,
            )
        else:
            return abort(404, 'Content unavailable')
    else:
        return abort(404, 'Content unavailable')
Ejemplo n.º 3
0
def fsDeleteFileView(fsPathString=''):
    """ Delete-file view.
        Permission checks are performed by the deleteFile filesystem call.
    """
    user = g.user
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, fileName, user)
    fsDeleteQueue = deleteFile(
        db,
        parentBox,
        file,
        user,
        fileStorageDirectory=fileStorageDirectory,
    )
    flushFsDeleteQueue(fsDeleteQueue)
    return redirect(url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    ))
Ejemplo n.º 4
0
def fsMetadataView(fsPathString=''):
    """Edit-file-metadata view, a web-form."""
    user = g.user
    db = dbGetDatabase()
    form = FileDataForm()
    lsPath = splitPathString(fsPathString)
    boxPath, prevFileName = lsPath[:-1], lsPath[-1]
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, prevFileName, user)
    if form.validate_on_submit():
        newFile = File(**recursivelyMergeDictionaries(
            {
                'name': form.filename.data,
                'description': form.filedescription.data,
                'metadata_username': user.username,
            },
            defaultMap=file.asDict(),
        ))
        updateFile(db, boxPath, prevFileName, newFile, user)
        return redirect(url_for('lsView', lsPathString='/'.join(boxPath[1:])))
    else:
        form.filename.data = applyDefault(form.filename.data, file.name)
        form.filedescription.data = applyDefault(form.filedescription.data,
                                                 file.description)
        #
        pageFeatures = {
            'breadCrumbs':
            makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[{
                    'kind': 'file',
                    'target': file,
                }, {
                    'kind': 'link',
                    'target': None,
                    'name': 'Metadata',
                }],
            ),
            'pageTitle':
            'Edit file metadata (%s)' % file.name,
            'pageSubtitle':
            'Name is mandatory',
            'iconUrl':
            url_for(
                'fileThumbnailView',
                dummyId=file.icon_file_id + '_',
                fsPathString='/'.join(lsPath[1:]),
            ),
        }
        return render_template(
            'filedataedit.html',
            form=form,
            user=user,
            **pageFeatures,
        )
Ejemplo n.º 5
0
def fileThumbnailView(dummyId, fsPathString):
    """Route for access to thumbnail image files based on file path."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, fileName, user)
    if (file is not None and file.icon_file_id is not None
            and file.icon_file_id != ''):
        filePhysicalPath, filePhysicalName = fileIdToSplitPath(
            file.icon_file_id,
            fileStorageDirectory=fileStorageDirectory,
        )
        return send_from_directory(
            filePhysicalPath,
            filePhysicalName,
            mimetype=file.icon_mime_type,
        )
    else:
        return redirect(pickFileThumbnail(file.mime_type))
Ejemplo n.º 6
0
def fsDoMoveFileView(quotedFilePath, quotedDestBox=''):
    """Move-file, view 2/2: dest box is selected, actually move."""
    user = g.user
    db = dbGetDatabase()
    # we retrieve the source file and the destination box
    srcFsPathString = urllib.parse.unquote_plus(quotedFilePath)
    srcLsPath = splitPathString(srcFsPathString)
    srcBoxPath, fileName = srcLsPath[:-1], srcLsPath[-1]
    srcBox = getBoxFromPath(db, srcBoxPath, user)
    file = getFileFromParent(db, srcBox, fileName, user)
    dstBoxPathString = urllib.parse.unquote_plus(quotedDestBox)
    dstBoxPath = splitPathString(dstBoxPathString)
    dstBox = getBoxFromPath(db, dstBoxPath, user)
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    #
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(srcBoxPath[1:]),
    )
    messages = moveFile(
        db,
        file,
        srcBox,
        dstBox,
        user,
        fileStorageDirectory=fileStorageDirectory,
    )
    for msg in messages:
        flashMessage('Info', 'Info', msg)
    return redirect(url_for(
        'lsView',
        lsPathString='/'.join(dstBoxPath[1:]),
    ))
Ejemplo n.º 7
0
def ticketFsDownloadView(ticketId, securityCode):
    """ Give-the-file-contents-based-on-ticket route.

        Helper endpoint to load-and-return a file upon a ticket;
        access to files based on a ticket.

        Used by both the direct-file-download or the view-file
        file-ticket modes.

        Note: punching occurs here.
    """
    user = g.user
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    #
    richTicket = dbGetEnrichAndCheckTicket(
        db,
        'f',
        ticketId,
        securityCode,
        request.url_root,
    )
    issuer = (dbGetUser(db, richTicket['ticket'].username)
              if richTicket is not None else None)
    noBandUsrTickets = g.settings['behaviour']['behaviour_tickets'][
        'protect_banned_user_tickets']['value']
    if (issuer is not None and (not noBandUsrTickets or issuer.banned == 0)):
        boxPath, fileName = (
            richTicket['metadata']['path'][:-1],
            richTicket['metadata']['path'][-1],
        )
        parentBox = getBoxFromPath(db, boxPath, issuer)
        #
        if parentBox is not None:
            file = getFileFromParent(db, parentBox, fileName, issuer)
            if file is not None:
                # return it and contextually punch the ticket
                dbPunchRichTicket(db, richTicket)
                # then we return the file as a download
                # (this flow assumes download is desired as opposed to view)
                filePhysicalPath, filePhysicalName = fileIdToSplitPath(
                    file.file_id,
                    fileStorageDirectory=fileStorageDirectory,
                )
                return send_from_directory(
                    filePhysicalPath,
                    filePhysicalName,
                    attachment_filename=file.name,
                    as_attachment=True,
                    mimetype=file.mime_type,
                )
            else:
                return abort(404, 'Content unavailable')
        else:
            return abort(404, 'Content unavailable')
    else:
        return abort(404, 'Content unavailable')
Ejemplo n.º 8
0
def fsHybridView(fsPathString=''):
    """ "Hybrid" file view: if it is a textually-viewable file
        (such as plaintext but most importantly markdown), show it as 'view';
        if it is anything else (especially an image), return it as 'download':
        this is to make sure embedding of images in markdown documents works
        as usual.
    """
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, fileName, user)
    isTextual = isFileTextViewable(file)
    if isTextual:
        return fsView(fsPathString=fsPathString)
    else:
        return fsDownloadView(fsPathString=fsPathString)
Ejemplo n.º 9
0
def fsMoveFileView(quotedFilePath):
    """Move-file, view 1/2: select destination box."""
    user = g.user
    db = dbGetDatabase()
    # first we find the file
    fsPathString = urllib.parse.unquote_plus(quotedFilePath)
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    parentBox = getBoxFromPath(db, boxPath, user)
    file = getFileFromParent(db, parentBox, fileName, user)
    # next we prepare the selectable destinations
    rootBox = getRootBox(db)

    def rbPredicate(richBox, idToAvoid=parentBox.box_id):
        return all((richBox['box'].box_id != idToAvoid,
                    userHasPermission(db, user, richBox['box'].permissions,
                                      'w')))

    dstBoxTree = collectTreeFromBox(
        db,
        rootBox,
        user,
        admitFiles=False,
        fileOrBoxEnricher=lambda richBox: {
            'obj_path': urllib.parse.quote_plus('/'.join(richBox['path'])),
        },
        predicate=rbPredicate,
    )
    #
    maxDepth = getMaxTreeDepth(dstBoxTree)
    colorShadeMap = prepareColorShadeMap(
        g.settings['color']['navigation_colors']['file']['value'],
        g.settings['color']['tree_shade_colors']['shade_treeview_pickbox']
        ['value'],
        numShades=1 + maxDepth,
    )
    destinationsExist = treeAny(
        dstBoxTree,
        property=lambda node: node['predicate'],
    )
    #
    return render_template(
        'dirtreeview.html',
        tree=dstBoxTree if destinationsExist else None,
        mode='file_move',
        object_quoted_path=quotedFilePath,
        colorShadeMap=colorShadeMap,
        user=user,
        iconUrl=makeSettingImageUrl(g, 'app_images', 'move'),
        pageTitle='Select file destination',
        pageSubtitle=(('Choose the box to which file "%s" shall '
                       'be moved from "%s"') % (
                           file.name,
                           describeBoxTitle(parentBox),
                       )),
        actions=None,
        backToUrl=None if destinationsExist else url_for(
            'lsView',
            lsPathString='/'.join(boxPath[1:]),
        ),
        breadCrumbs=makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[{
                'kind': 'file',
                'target': file,
            }, {
                'kind': 'link',
                'target': None,
                'name': 'Move file',
            }],
        ),
    )
Ejemplo n.º 10
0
def saveAndAnalyseFilesInBox(db,
                             files,
                             parentBox,
                             user,
                             thumbnailFormat,
                             fileStorageDirectory,
                             pastActionVerbForm='uploaded'):
    """ Save files and enrich them with type/mimetype,
        unless something fails - this handles overwrites
        (file-on-file) and blockades (file has same name as box)
    """
    #
    # checking for name clashes with boxes
    if any(
            isBoxNameUnderParentBox(db, parentBox, fName)
            for fName in (fObj['name'] for fObj in files)):
        raise OstracionError('Files cannot have the name of existing boxes')
    else:
        if not userHasPermission(db, user, parentBox.permissions, 'w'):
            raise OstracionError('User has no write permission on this box')
        else:
            userName = user.username
            fsDeletionQueue = []
            numReplacements = 0
            #
            for file in files:
                newFile = File(**recursivelyMergeDictionaries(
                    {k: v
                     for k, v in file.items() if k != 'fileObject'},
                    defaultMap={
                        'creator_username': userName,
                        'icon_file_id_username': userName,
                        'metadata_username': userName,
                        'editor_username': userName,
                        'textual_mode': 'plain',
                    },
                ))
                # are we overwriting a file?
                if isFileNameUnderParentBox(db, parentBox, newFile.name):
                    # delete the old file entry
                    # AND mark the file and its thumbnail
                    # (if any) for later deletion
                    prevFile = getFileFromParent(
                        db,
                        parentBox,
                        newFile.name,
                        user,
                    )
                    fsDeletionQueue += deleteFile(
                        db,
                        parentBox,
                        prevFile,
                        user,
                        fileStorageDirectory=fileStorageDirectory,
                        skipCommit=True,
                    )
                    numReplacements += 1
                #
                filePath = fileIdToPath(
                    newFile.file_id,
                    fileStorageDirectory=fileStorageDirectory,
                )
                file['fileObject'].save(filePath)
                #
                fileProperties = determineFileProperties(filePath)
                newFile.mime_type = fileProperties['file_mime_type']
                newFile.type = fileProperties['file_type']
                newFile.size = fileProperties['file_size']
                #
                if (thumbnailFormat is not None
                        and isImageMimeType(newFile.mime_type)):
                    # thumbnail preparation
                    fileThumbnailId, fileThumbnailMimeType = makeFileThumbnail(
                        newFile.file_id,
                        newFile.mime_type,
                        thumbnailFormat=thumbnailFormat,
                        fileStorageDirectory=fileStorageDirectory,
                    )
                    if fileThumbnailId is not None:
                        newFile.icon_file_id = fileThumbnailId
                        newFile.icon_mime_type = fileThumbnailMimeType
                #
                makeFileInParent(db, parentBox=parentBox, newFile=newFile)
            flushFsDeleteQueue(fsDeletionQueue)
            db.commit()
            return '%i file%s %s successfully%s.' % (
                len(files), '' if len(files) == 1 else 's', pastActionVerbForm,
                '' if numReplacements == 0 else
                (' (%i replaced)' % numReplacements))
Ejemplo n.º 11
0
def _traverseForAccountDeletion(db, parentBox, username, user,
                                path, fileStorageDirectory):
    """ Traverse the tree (one call per box, recursively+iteratively)
        and collect a delete queue while updating items found in various
        ways (deletions, icon resets, metadata resets, forced renames).
    """
    fsDeleteQueue = []
    for file in getFilesFromBox(db, parentBox):
        if (file.creator_username == username or
                file.editor_username == username):
            fsDeleteQueue += deleteFile(
                db,
                parentBox,
                file,
                None,
                fileStorageDirectory=fileStorageDirectory,
                skipCommit=True,
                accountDeletionInProgress=True,
            )
        else:
            if file.icon_file_id_username == username:
                fsDeleteQueue += updateFileThumbnail(
                    db,
                    file,
                    None,
                    None,
                    user,
                    fileStorageDirectory=fileStorageDirectory,
                    accountDeletionInProgress=True,
                    skipCommit=True,
                )
                iconedFile = getFileFromParent(db, parentBox, file.name, None)
            else:
                iconedFile = file
            # "iconed" as in "icon-wise fixed"
            if iconedFile.metadata_username == username:
                newFileName = findFirstAvailableObjectNameInBox(
                    db,
                    parentBox,
                    prefix='REDACTED_FILE_',
                    suffix='',
                )
                newDescription = 'File name redacted upon account deletion'
                newFile = File(**recursivelyMergeDictionaries(
                    {
                        'name': newFileName,
                        'description': newDescription,
                        'metadata_username': '',
                    },
                    defaultMap=iconedFile.asDict(),
                ))
                updateFile(
                    db,
                    path,
                    iconedFile.name,
                    newFile,
                    None,
                    accountDeletionInProgress=True,
                    skipCommit=True,
                )
    #
    for link in getLinksFromBox(db, parentBox):
        if link.creator_username == username:
            fsDeleteQueue += deleteLink(
                db,
                parentBox,
                link,
                None,
                fileStorageDirectory=fileStorageDirectory,
                skipCommit=True,
                accountDeletionInProgress=True,
            )
        else:
            if link.icon_file_id_username == username:
                fsDeleteQueue += updateLinkThumbnail(
                    db,
                    link,
                    None,
                    None,
                    user,
                    fileStorageDirectory=fileStorageDirectory,
                    accountDeletionInProgress=True,
                    skipCommit=True,
                )
                iconedLink = getLinkFromParent(db, parentBox, link.name, None)
            else:
                iconedLink = link
            # "iconed" as in "icon-wise fixed"
            if iconedLink.metadata_username == username:
                newLinkName = findFirstAvailableObjectNameInBox(
                    db,
                    parentBox,
                    prefix='REDACTED_LINK_',
                    suffix='',
                )
                newDescription = 'Link data redacted upon account deletion'
                newLink = Link(**recursivelyMergeDictionaries(
                    {
                        'name': newLinkName,
                        'description': newDescription,
                        'target': '#',
                        'metadata_username': '',
                    },
                    defaultMap=iconedLink.asDict(),
                ))
                updateLink(
                    db,
                    path,
                    iconedLink.name,
                    newLink,
                    None,
                    accountDeletionInProgress=True,
                    skipCommit=True,
                )
    #
    for box in getBoxesFromParent(
            db, parentBox, None, accountDeletionInProgress=True):
        if box is not None and box.box_name != '':
            fsDeleteQueue += _traverseForAccountDeletion(
                db,
                box,
                username,
                user,
                path + [box.box_name],
                fileStorageDirectory=fileStorageDirectory,
            )
            if box.creator_username == username and _boxHasNoChildren(db, box):
                fsDeleteQueue += deleteBox(
                    db,
                    box,
                    parentBox,
                    None,
                    fileStorageDirectory=fileStorageDirectory,
                    accountDeletionInProgress=True,
                    skipCommit=True,
                )
            else:
                if (box.icon_file_id_username == username or
                        box.creator_username == username):
                    fsDeleteQueue += updateBoxThumbnail(
                        db,
                        box,
                        None,
                        None,
                        user,
                        fileStorageDirectory=fileStorageDirectory,
                        accountDeletionInProgress=True,
                        skipCommit=True,
                    )
                    iconedBox = getBoxFromPath(
                        db,
                        path + [box.box_name],
                        None,
                        accountDeletionInProgress=True,
                    )
                else:
                    iconedBox = box
                #
                if (iconedBox.metadata_username == username or
                        iconedBox.creator_username == username):
                    #
                    newBoxName = findFirstAvailableObjectNameInBox(
                        db,
                        parentBox,
                        prefix='REDACTED_BOX_',
                        suffix='',
                    )
                    newDescription = 'Box name redacted upon account deletion'
                    mdNewBoxContrib = {
                            'box_name': newBoxName,
                            'description': newDescription,
                            'title': newBoxName,
                            'metadata_username': '',
                    }
                    #
                    if iconedBox.creator_username == username:
                        cNewBoxContrib = {
                            'creator_username': '',
                        }
                    else:
                        cNewBoxContrib = {}
                    #
                    newBox = Box(**recursivelyMergeDictionaries(
                        recursivelyMergeDictionaries(
                            mdNewBoxContrib,
                            defaultMap=cNewBoxContrib,
                        ),
                        defaultMap=iconedBox.asDict(),
                    ))
                    updateBox(
                        db,
                        path + [box.box_name],
                        newBox,
                        None,
                        accountDeletionInProgress=True,
                        skipCommit=True,
                    )
    #
    return fsDeleteQueue
Ejemplo n.º 12
0
def fsMakeTicketView(fsPathString=''):
    """Create-file-ticket (file-read) view."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    if parentBox is not None:
        file = getFileFromParent(db, parentBox, fileName, user)
        if file is not None:
            pathBCrumbs = makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[
                    {
                        'kind': 'file',
                        'target': file,
                    },
                    {
                        'name':
                        '(create ticket)',
                        'kind':
                        'link',
                        'target':
                        url_for(
                            'fsMakeTicketView',
                            fsPathString=fsPathString,
                        ),
                        'link':
                        False,
                    },
                ],
            )
            # if this succeeded, user has read permission on 'file'
            form = generateFsTicketForm(
                fileModePresent=True,
                settings=g.settings,
            )
            if form.validate_on_submit():
                magicLink = dbMakeFileTicket(
                    db=db,
                    ticketName=form.name.data,
                    validityHours=transformIfNotEmpty(
                        form.validityhours.data,
                        int,
                    ),
                    multiplicity=transformIfNotEmpty(
                        form.multiplicity.data,
                        int,
                    ),
                    ticketMessage=transformIfNotEmpty(
                        form.ticketmessage.data, ),
                    file=file,
                    fileMode=form.filemode.data,
                    lsPath=lsPath,
                    user=user,
                    urlRoot=request.url_root,
                    settings=g.settings,
                )
                flashMessage(
                    'Success',
                    'Done',
                    ('File ticket generated. Give the recipient '
                     'the following magic link:'),
                    pillText=magicLink,
                )
                return redirect(
                    url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:]),
                    ))
            else:
                form.name.data = applyDefault(form.name.data, file.name)
                form.ticketmessage.data = applyDefault(
                    form.ticketmessage.data,
                    'Please access this file',
                )
                form.filemode.data = applyDefault(
                    form.filemode.data,
                    'direct',
                    additionalNulls=['None'],
                )
                maxValidityHours = g.settings['behaviour'][
                    'behaviour_tickets']['max_ticket_validityhours']['value']
                form.validityhours.data = applyDefault(
                    form.validityhours.data,
                    (str(maxValidityHours)
                     if maxValidityHours is not None else ''),
                )
                maxMultiplicity = g.settings['behaviour']['behaviour_tickets'][
                    'max_ticket_multiplicity']['value']
                form.multiplicity.data = applyDefault(
                    form.multiplicity.data,
                    (str(maxMultiplicity)
                     if maxMultiplicity is not None else ''),
                )
                return render_template(
                    'fsticket.html',
                    pageTitle='Create public file ticket',
                    pageSubtitle=('Recipient(s) of the ticket will be able '
                                  'to access "%s" without an account.') %
                    (fsPathString, ),
                    baseMultiplicityCaption=('Number of granted accesses (bo'
                                             'th views and downloads count)'),
                    user=user,
                    form=form,
                    iconUrl=makeSettingImageUrl(
                        g,
                        'app_images',
                        'file_ticket',
                    ),
                    showFileMode=True,
                    breadCrumbs=pathBCrumbs,
                )
        else:
            return abort(404)
    else:
        return abort(404)
Ejemplo n.º 13
0
def editTextFileView(fsPathString=''):
    """Edit-text-file route."""
    user = g.user
    db = dbGetDatabase()
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    file = getFileFromParent(db, parentBox, fileName, user)
    if file is None:
        raise OstracionError('File not found.')
    else:
        fileActions = prepareFileActions(
            db,
            file,
            boxPath[1:] + [file.name],
            parentBox,
            user,
            discardedActions={'text_edit'},
        )
        fileInfo = prepareFileInfo(db, file)
        form = EditTextFileForm()
        form.textformat.choices = [
            (mId, mDesc['title'])
            for mId, mDesc in sorted(
                textFileViewingModes.items(),
                key=lambda kv: kv[1]['index'],
            )
        ]
        ##
        if form.validate_on_submit():
            newcontents = form.filecontents.data
            filePath = fileIdToPath(
                file.file_id,
                fileStorageDirectory=fileStorageDirectory,
            )
            with open(filePath, 'w') as openFile:
                openFile.write('%s' % newcontents)
            # file properties
            fileProperties = determineFileProperties(filePath)
            newFile = File(**file.asDict())
            newFile.mime_type = fileProperties['file_mime_type']
            newFile.type = fileProperties['file_type']
            newFile.size = fileProperties['file_size']
            newFile.textual_mode = form.textformat.data
            newFile.editor_username = user.username
            updateFile(db, boxPath, file.name, newFile, user)
            #
            flashMessage('Info', 'Info', 'File "%s" saved.' % file.name)
            return redirect(
                url_for(
                    'lsView',
                    lsPathString='/'.join(boxPath[1:]),
                )
            )
        else:
            form.filecontents.data = applyDefault(
                form.filecontents.data,
                open(
                    fileIdToPath(
                        file.file_id,
                        fileStorageDirectory=fileStorageDirectory,
                    )
                ).read(),
            )
            form.textformat.data = applyDefault(
                form.textformat.data,
                file.textual_mode,
                additionalNulls=['None'],
            )
            pathBCrumbs = makeBreadCrumbs(
                boxPath,
                g,
                appendedItems=[
                    {
                        'kind': 'file',
                        'target': file,
                    },
                    {
                        'kind': 'link',
                        'target': None,
                        'name': 'Edit text',
                    }
                ],
            )
            return render_template(
                'edittextfile.html',
                user=user,
                form=form,
                fileActions=fileActions,
                fileInfo=fileInfo,
                pageTitle='"%s" file edit' % file.name,
                pageSubtitle='Click "Save" to commit the changes',
                breadCrumbs=pathBCrumbs,
            )
Ejemplo n.º 14
0
def retrieveFileUponTicket(db, user, issuer, richTicket, urlRoot):
    """ Retrieve a file using a file ticket.

        Retrieval fails if either:
            1. user banned;
            2. object not available to the issuer.
    """
    noBandUsrTickets = g.settings['behaviour']['behaviour_tickets'][
        'protect_banned_user_tickets']['value']
    if (not noBandUsrTickets or issuer.banned == 0):
        boxPath, fileName = (
            richTicket['metadata']['path'][:-1],
            richTicket['metadata']['path'][-1],
        )
        fileStorageDirectory = g.settings['system']['system_directories'][
            'fs_directory']['value']
        parentBox = getBoxFromPath(db, boxPath, issuer)
        #
        if parentBox is not None:
            file = getFileFromParent(db, parentBox, fileName, issuer)
            if file is not None:
                if richTicket['metadata'].get('file_mode') == 'view':
                    # either we offer a view-type page
                    # (with ticketMessage and optionally view)
                    # and decide whether to punch the ticket and how ...
                    fileRetrievalUrl = url_for(
                        'ticketFsDownloadView',
                        ticketId=richTicket['ticket'].ticket_id,
                        securityCode=richTicket['ticket'].security_code,
                    )
                    # for mode='ticketview'this will internally call
                    # the punching endpoint 'ticketFsDownloadView' below.
                    fileContents = produceFileViewContents(
                        db,
                        file,
                        mode='ticketview',
                        viewParameters={
                            'ticketId': richTicket['ticket'].ticket_id,
                            'securityCode': richTicket['ticket'].security_code,
                        },
                        fileStorageDirectory=fileStorageDirectory,
                        urlRoot=urlRoot,
                        protectBannedUserTickets=noBandUsrTickets,
                    )
                    return render_template(
                        'fileview.html',
                        fileActions=None,
                        fileInfo=None,
                        filecontents=fileContents,
                        breadCrumbs=[],
                        user=user,
                        pageTitle='File access',
                        pageSubtitle='View/download the file%s' %
                        ('' if richTicket['metadata'].get('message') is None
                         else ('. Message on ticket: "%s"' %
                               (richTicket['metadata']['message']))),
                        downloadUrl=fileRetrievalUrl,
                    )
                elif richTicket['metadata'].get('file_mode') == 'direct':
                    # ... or we offer a direct download and punch the ticket...
                    return ticketFsDownloadView(
                        richTicket['ticket'].ticket_id,
                        richTicket['ticket'].security_code,
                    )
                else:
                    raise NotImplementedError(
                        'Unknown file_mode "%s" in file ticket' %
                        (richTicket['metadata'].get('file_mode'), ))
            else:
                raise OstracionError('Ticket target unavailable')
        else:
            raise OstracionError('Ticket target unavailable')
    else:
        raise OstracionError('Ticket cannot be redeemed')
Ejemplo n.º 15
0
def fsView(fsPathString=''):
    """View file route. If not viewable, display an error message."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, fileName = lsPath[:-1], lsPath[-1]
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBox = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    file = getFileFromParent(db, parentBox, fileName, user)
    if file is not None:
        fileInfo = prepareFileInfo(db, file)
        fileActions = prepareFileActions(
            db,
            file,
            boxPath[1:] + [file.name],
            parentBox,
            user,
            discardedActions={'view'},
        )
        fileContents = produceFileViewContents(
            db,
            file,
            mode='fsview',
            viewParameters={
                'boxPath': boxPath,
                'fileName': fileName,
            },
            fileStorageDirectory=fileStorageDirectory,
        )
        #
        pathBCrumbs = makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[{
                'kind': 'file',
                'target': file,
            }],
        )
        #
        return render_template(
            'fileview.html',
            fileActions=fileActions,
            fileInfo=fileInfo,
            filecontents=fileContents,
            breadCrumbs=pathBCrumbs,
            user=user,
            pageTitle='"%s" file view' % file.name,
            pageSubtitle='%s (%s; %s)' % (
                file.description,
                file.type,
                formatBytesSize(file.size),
            ),
            downloadUrl=None,
        )
    else:
        return abort(404)
Ejemplo n.º 16
0
def setIconView(mode, itemPathString=''):
    """ Route to set/replace the thumbnail of various items."""
    if (mode == 'au' and not g.settings['behaviour']['behaviour_admin_powers']
        ['admin_is_god']['value']):
        request._onErrorUrl = url_for('adminHomeUsersView')
        raise OstracionError('This feature is turned off in the configuration')
    else:
        user = g.user
        form = UploadIconForm()
        db = dbGetDatabase()
        tempFileDirectory = g.settings['system']['system_directories'][
            'temp_directory']['value']
        fileStorageDirectory = g.settings['system']['system_directories'][
            'fs_directory']['value']
        if mode == 'b':
            boxPath = splitPathString(itemPathString)
            request._onErrorUrl = url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            )
            parentBox = None
            thisItem = getBoxFromPath(db, boxPath, user)
            itemName = thisItem.getName()
            pageFeatures = {
                'breadCrumbs':
                makeBreadCrumbs(
                    splitPathString(itemPathString),
                    g,
                    appendedItems=[{
                        'kind': 'link',
                        'target': None,
                        'name': 'Icon',
                    }],
                ),
            }
        elif mode == 'f':
            fullPath = splitPathString(itemPathString)
            boxPath, fileName = fullPath[:-1], fullPath[-1]
            request._onErrorUrl = url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            )
            parentBox = getBoxFromPath(db, boxPath, user)
            thisItem = getFileFromParent(db, parentBox, fileName, user)
            itemName = thisItem.getName()
            pageFeatures = {
                'breadCrumbs':
                makeBreadCrumbs(
                    splitPathString(itemPathString)[:-1],
                    g,
                    appendedItems=[{
                        'kind': 'file',
                        'target': thisItem,
                    }, {
                        'kind': 'link',
                        'target': None,
                        'name': 'Icon',
                    }],
                ),
            }
        elif mode == 'l':
            fullPath = splitPathString(itemPathString)
            boxPath, linkName = fullPath[:-1], fullPath[-1]
            request._onErrorUrl = url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            )
            parentBox = getBoxFromPath(db, boxPath, user)
            thisItem = getLinkFromParent(db, parentBox, linkName, user)
            itemName = thisItem.getName()
            pageFeatures = {
                'breadCrumbs':
                makeBreadCrumbs(
                    splitPathString(itemPathString)[:-1],
                    g,
                    appendedItems=[{
                        'kind': 'external_link',
                        'target': thisItem,
                    }, {
                        'kind': 'link',
                        'target': None,
                        'name': 'Icon',
                    }],
                ),
            }
        elif mode == 'u':
            pageFeatures = prepareTaskPageFeatures(
                userProfilePageDescriptor,
                ['root', 'icon'],
                g,
                overrides={
                    'pageTitle': None,
                    'pageSubtitle': None,
                    'iconUrl': None,
                },
            )
            thisItem = user
            itemName = thisItem.getName()
            parentBox = None
        elif mode == 'au':
            pageFeatures = prepareTaskPageFeatures(
                adminPageDescriptor,
                ['root', 'users'],
                g,
                appendedItems=[{
                    'kind': 'link',
                    'link': False,
                    'target': None,
                    'name': 'Icon',
                }],
                overrides={
                    'pageTitle': None,
                    'pageSubtitle': None,
                    'iconUrl': None,
                },
            )
            if userIsAdmin(db, user):
                thisItem = dbGetUser(db, itemPathString)
                itemName = thisItem.getName()
                parentBox = None
            else:
                raise OstracionError('Insufficient permissions')
        elif mode == 's':
            pageFeatures = prepareTaskPageFeatures(
                adminPageDescriptor,
                ['root', 'settings', 'images'],
                g,
                appendedItems=[{
                    'kind': 'link',
                    'link': False,
                    'target': None,
                    'name': 'Set image',
                }],
                overrides={
                    'pageTitle': None,
                    'pageSubtitle': None,
                    'iconUrl': None,
                },
            )
            if userIsAdmin(db, user):
                settingGroupId, settingId = itemPathString.split('/')
                thisItem = g.settings['image'][settingGroupId][settingId]
                itemName = thisItem['setting'].getName()
                parentBox = None
            else:
                raise OstracionError('Insufficient permissions')
        else:
            raise RuntimeError('Unknown mode encountered')
        #
        if form.validate_on_submit():
            #
            storageSuccess = storeFileAsThumbnail(
                db,
                fileToSave=form.file.data,
                mode=mode,
                thumbnailFormat=determineThumbnailFormatByModeAndTarget(
                    db,
                    mode,
                    thisItem,
                ),
                targetItem=thisItem,
                parentBox=parentBox,
                user=user,
                tempFileDirectory=tempFileDirectory,
                fileStorageDirectory=fileStorageDirectory,
            )
            if not storageSuccess:
                raise OstracionError('Could not set the icon')
            #
            if mode in {'f', 'b', 'l'}:
                return redirect(
                    url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:-1] if mode ==
                                              'b' else boxPath[1:]),
                    ))
            elif mode == 'u':
                return redirect(url_for('userProfileView', ))
            elif mode == 'au':
                return redirect(url_for('adminHomeUsersView', ))
            elif mode == 's':
                return redirect(url_for('adminHomeSettingsImagesView', ))
            else:
                raise RuntimeError('Unknown mode encountered')
        else:
            #
            titleMap = {
                'f': 'Set File Icon',
                'l': 'Set Link Icon',
                'b': 'Set Box Icon',
                'u': 'Set User Icon',
                'au': 'Set User Icon (as admin)',
                's': 'Set Application Image',
            }
            modeNameMap = {
                'f': 'for file',
                'l': 'for link',
                'b': 'for box',
                'u': 'for user',
                'au': '(as admin) for user',
                's': 'for setting',
            }
            finalPageFeatures = recursivelyMergeDictionaries(
                {
                    'pageTitle':
                    titleMap[mode],
                    'pageSubtitle':
                    'Upload an image file %s "%s"' % (
                        modeNameMap[mode],
                        itemName,
                    ),
                },
                defaultMap=pageFeatures,
            )
            if mode == 'u':
                finalPageFeatures['iconUrl'] = url_for(
                    'userThumbnailView',
                    dummyId='%s_' % thisItem.icon_file_id,
                    username=thisItem.username,
                )
            elif mode == 'au':
                finalPageFeatures['iconUrl'] = url_for(
                    'userThumbnailView',
                    dummyId='%s_' % thisItem.icon_file_id,
                    username=thisItem.username,
                )
            elif mode == 's':
                finalPageFeatures['iconUrl'] = makeSettingImageUrl(
                    g,
                    settingGroupId,
                    settingId,
                )
            elif mode == 'b':
                finalPageFeatures['iconUrl'] = url_for(
                    'boxThumbnailView',
                    dummyId=thisItem.icon_file_id + '_',
                    boxPathString='/'.join(boxPath[1:]),
                )
            elif mode == 'f':
                finalPageFeatures['iconUrl'] = url_for(
                    'fileThumbnailView',
                    dummyId=thisItem.icon_file_id + '_',
                    fsPathString='/'.join(boxPath[1:] + [thisItem.name]),
                )
            elif mode == 'l':
                finalPageFeatures['iconUrl'] = url_for(
                    'linkThumbnailView',
                    dummyId=thisItem.icon_file_id + '_',
                    fsPathString='/'.join(boxPath[1:] + [thisItem.name]),
                )
            #
            return render_template(
                'uploadicon.html',
                form=form,
                user=user,
                mode=mode,
                itemPathString=itemPathString,
                **finalPageFeatures,
            )
Ejemplo n.º 17
0
def fsGalleryView(fsPathString=''):
    """ Gallery view route on a box.
        If just box, redirect to first file.
        If a file, use the ls of files to prepare prev/next links.

        That is to say, if user has read permission on box, gallery URLs are
        not index-based, rather filename-based and recalculated on actual 'ls'.
    """
    isTopAccess = 1 if safeInt(request.args.get('top'), 0) != 0 else 0
    user = g.user
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    db = dbGetDatabase()
    lsPath = splitPathString(fsPathString)
    # is it a box or a file?
    targetBox = getBoxFromPath(db, lsPath, user)
    if targetBox is not None:
        # if there are files, we redirect to the first one
        # otherwise, a message and falling back to ls view of the box
        files = sorted(
            getFilesFromBox(db, targetBox),
            key=lambda f: (f.name.lower(), f.name),
        )
        if len(files) > 0:
            return redirect(
                url_for(
                    'fsGalleryView',
                    fsPathString='/'.join(lsPath[1:] + [files[0].name]),
                    top=str(isTopAccess),
                ))
        else:
            flashMessage(
                'Info',
                'Empty box',
                'Cannot view as gallery a box without files',
            )
            return redirect(
                url_for(
                    'lsView',
                    lsPathString='/'.join(lsPath[1:]),
                ))
    else:
        # is it a file?
        boxPath, fileName = lsPath[:-1], lsPath[-1]
        parentBox = getBoxFromPath(db, boxPath, user)
        file = getFileFromParent(db, parentBox, fileName, user)
        if file is not None:
            if isTopAccess:
                # gallery navigation calculations
                files = sorted(
                    getFilesFromBox(db, parentBox),
                    key=lambda f: (f.name.lower(), f.name),
                )
                thisFileIndex = [
                    idx for idx, fil in enumerate(files)
                    if fil.name == fileName
                ][0]
                numGalleryFiles = len(files)
                nextFileIndex = (thisFileIndex + 1) % numGalleryFiles
                prevFileIndex = (thisFileIndex - 1 +
                                 numGalleryFiles) % numGalleryFiles
                #
                pathBCrumbs = makeBreadCrumbs(
                    boxPath,
                    g,
                    appendedItems=[{
                        'kind':
                        'link',
                        'name':
                        'Gallery view %i/%i' % (
                            thisFileIndex + 1,
                            numGalleryFiles,
                        ),
                        'target':
                        None,
                    }],
                )
                fileContents = produceFileViewContents(
                    db,
                    file,
                    mode='fsview',
                    viewParameters={
                        'boxPath': boxPath,
                        'fileName': fileName,
                    },
                    fileStorageDirectory=fileStorageDirectory,
                )
                fileActions = {
                    'gallery_prev':
                    url_for(
                        'fsGalleryView',
                        fsPathString='/'.join(boxPath[1:] +
                                              [files[prevFileIndex].name]),
                        top=str(isTopAccess),
                    ),
                    'gallery_next':
                    url_for(
                        'fsGalleryView',
                        fsPathString='/'.join(boxPath[1:] +
                                              [files[nextFileIndex].name]),
                        top=str(isTopAccess),
                    ),
                    'gallery_up':
                    url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:]),
                    ),
                    'download':
                    url_for(
                        'fsDownloadView',
                        fsPathString=fsPathString,
                    ),
                }
                return render_template(
                    'fileview.html',
                    fileActions=fileActions,
                    fileInfo=None,
                    filecontents=fileContents,
                    breadCrumbs=pathBCrumbs,
                    user=user,
                    pageTitle='"%s" gallery, file "%s" (%i/%i)' % (
                        parentBox.title,
                        file.name,
                        thisFileIndex + 1,
                        numGalleryFiles,
                    ),
                    pageSubtitle=file.description,
                    downloadUrl=None,
                    hideBreadCrumbs=True,
                    hideNavbar=True,
                )
            else:
                return fsDownloadView(fsPathString=fsPathString)
        else:
            # extreme fallback to ls, which will hiearchically
            # deal with the retrieval
            return redirect(url_for('lsView', lsPathString=fsPathString))
Ejemplo n.º 18
0
def _resolveUponPermissions(db, richObject, user, mode, score):
    """ Verify and validate the input (rich-)box/file
        against permissions, and return either a similar structure
        or a None if permissions turn out to be blocking.

        (
            richObject has keys "path" and "box/file",
            mode = 'file' / 'box'
        )
    """
    pBox = getBoxFromPath(db, richObject['path'][:-1], user)
    if mode == 'box':
        nBox = getBoxFromPath(db, richObject['path'], user)
        if nBox is not None and pBox is not None:
            return {
                'path':
                richObject['path'][1:],
                'box':
                nBox,
                'actions':
                prepareBoxActions(db,
                                  nBox,
                                  richObject['path'][1:],
                                  pBox,
                                  user,
                                  prepareParentButton=True),
                'info':
                prepareBoxInfo(db, nBox),
                'parentInfo':
                'Parent box: "%s"' % (describeBoxTitle(pBox), ),
                'object_type':
                mode,
                'score':
                score,
            }
        else:
            return None
    elif mode == 'file':
        if pBox is not None:
            nFile = getFileFromParent(db, pBox, richObject['path'][-1], user)
            if nFile is not None:
                return {
                    'path':
                    richObject['path'][1:],
                    'file':
                    nFile,
                    'actions':
                    prepareFileActions(db,
                                       nFile,
                                       richObject['path'][1:],
                                       pBox,
                                       user,
                                       prepareParentButton=True),
                    'info':
                    prepareFileInfo(db, nFile),
                    'nice_size':
                    formatBytesSize(nFile.size),
                    'parentInfo':
                    'Container box: "%s"' % (describeBoxTitle(pBox), ),
                    'object_type':
                    mode,
                    'score':
                    score,
                }
            else:
                return None
        else:
            return None
    elif mode == 'link':
        if pBox is not None:
            nLink = getLinkFromParent(db, pBox, richObject['path'][-1], user)
            if nLink is not None:
                return {
                    'path':
                    richObject['path'][1:],
                    'link':
                    nLink,
                    'actions':
                    prepareLinkActions(db,
                                       nLink,
                                       richObject['path'][1:],
                                       pBox,
                                       user,
                                       prepareParentButton=True),
                    'info':
                    prepareLinkInfo(db, nLink),
                    'parentInfo':
                    'Container box: "%s"' % (describeBoxTitle(pBox), ),
                    'object_type':
                    mode,
                    'score':
                    score,
                }
            else:
                return None
        else:
            return None
    else:
        raise NotImplementedError('Unknown _resolveUponPermissions mode "%s"' %
                                  mode)
Ejemplo n.º 19
0
def unsetIconView(mode, itemPathString=''):
    """Route for explicit removal of thumbnail, if any, to various items."""
    if (mode == 'au' and not g.settings['behaviour']['behaviour_admin_powers']
        ['admin_is_god']['value']):
        request._onErrorUrl = url_for('adminHomeUsersView')
        raise OstracionError('This feature is turned off in the configuration')
    else:
        user = g.user
        form = UploadIconForm()
        db = dbGetDatabase()
        #
        tempFileDirectory = g.settings['system']['system_directories'][
            'temp_directory']['value']
        fileStorageDirectory = g.settings['system']['system_directories'][
            'fs_directory']['value']
        #
        if mode == 'b':
            modeName = 'box'
            boxPath = splitPathString(itemPathString)
            thisItem = getBoxFromPath(db, boxPath, user)
            parentBox = None
        elif mode == 'f':
            modeName = 'file'
            fullPath = splitPathString(itemPathString)
            boxPath, fileName = fullPath[:-1], fullPath[-1]
            parentBox = getBoxFromPath(db, boxPath, user)
            thisItem = getFileFromParent(db, parentBox, fileName, user)
        elif mode == 'l':
            modeName = 'link'
            fullPath = splitPathString(itemPathString)
            boxPath, linkName = fullPath[:-1], fullPath[-1]
            parentBox = getBoxFromPath(db, boxPath, user)
            thisItem = getLinkFromParent(db, parentBox, linkName, user)
        elif mode == 'u':
            modeName = 'user'
            parentBox = None
            thisItem = user
        elif mode == 'au':
            modeName = 'adminuser'
            if userIsAdmin(db, user):
                thisItem = dbGetUser(db, itemPathString)
                parentBox = None
            else:
                raise OstracionError('Insufficient permissions')
        elif mode == 's':
            modeName = 'settingIcon'
            if userIsAdmin(db, user):
                settingGroupId, settingId = itemPathString.split('/')
                thisItem = g.settings['image'][settingGroupId][settingId]
                parentBox = None
            else:
                raise OstracionError('Insufficient permissions')
        else:
            raise RuntimeError('Unknown mode encountered')
        #
        storageSuccess = storeFileAsThumbnail(
            db,
            fileToSave=None,
            mode=mode,
            thumbnailFormat=determineThumbnailFormatByModeAndTarget(
                db,
                mode,
                thisItem,
            ),
            targetItem=thisItem,
            parentBox=parentBox,
            user=user,
            tempFileDirectory=tempFileDirectory,
            fileStorageDirectory=fileStorageDirectory,
        )
        if not storageSuccess:
            raise OstracionError('Could not unset the icon')
        #
        if mode in {'f', 'b', 'l'}:
            return redirect(
                url_for(
                    'lsView',
                    lsPathString='/'.join(boxPath[1:-1] if mode ==
                                          'b' else boxPath[1:]),
                ))
        elif mode == 'u':
            return redirect(url_for('userProfileView', ))
        elif mode == 'au':
            return redirect(url_for('adminHomeUsersView', ))
        elif mode == 's':
            return redirect(url_for('adminHomeSettingsImagesView', ))
        else:
            raise RuntimeError('Unknown mode encountered')