コード例 #1
0
def boxThumbnailView(dummyId, boxPathString=''):
    """Route for access to thumbnail image files based on box path."""
    user = g.user
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    if boxPathString == '':
        # root case
        return redirect(makeSettingImageUrl(g, 'app_images', 'root_box'))
    else:
        db = dbGetDatabase()
        boxPath = splitPathString(boxPathString)
        request._onErrorUrl = url_for(
            'lsView',
            lsPathString='/'.join(boxPath[1:]),
        )
        box = getBoxFromPath(db, boxPath, user)
        if (box is not None and box.icon_file_id is not None
                and box.icon_file_id != ''):
            filePhysicalPath, filePhysicalName = fileIdToSplitPath(
                box.icon_file_id,
                fileStorageDirectory=fileStorageDirectory,
            )
            return send_from_directory(
                filePhysicalPath,
                filePhysicalName,
                mimetype=box.icon_mime_type,
            )
        else:
            return redirect(
                makeSettingImageUrl(
                    g,
                    'app_images',
                    'standard_box',
                ))
コード例 #2
0
def extractTopLevelTaskFromTreeDescriptor(tDesc, bgColorKey, g, overrides={}):
    """ Pick the top-level task item from a tree-descriptor
        and format it in a way fit for ls-view tasks.
    """
    rootTask = tDesc['tasks']['root']
    return recursivelyMergeDictionaries(
        overrides,
        defaultMap={
            'name':
            rootTask['title'],
            'description':
            rootTask['subtitle'],
            'url':
            url_for(
                rootTask['endpoint_name'][0],
                **rootTask['endpoint_name'][1],
            ),
            'thumbnail':
            makeSettingImageUrl(
                g,
                rootTask['image_id'][0],
                rootTask['image_id'][1],
            ),
            'bgcolor':
            g.settings['color']['task_colors'][bgColorKey]['value'],
        })
コード例 #3
0
def linkThumbnailView(dummyId, fsPathString=''):
    """Route for access to thumbnail image files based on link path."""
    user = g.user
    lsPath = splitPathString(fsPathString)
    boxPath, linkName = 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:]),
    )
    link = getLinkFromParent(db, parentBox, linkName, user)
    if (link is not None and link.icon_file_id is not None
            and link.icon_file_id != ''):
        filePhysicalPath, filePhysicalName = fileIdToSplitPath(
            link.icon_file_id,
            fileStorageDirectory=fileStorageDirectory,
        )
        return send_from_directory(
            filePhysicalPath,
            filePhysicalName,
            mimetype=link.icon_mime_type,
        )
    else:
        return redirect(makeSettingImageUrl(g, 'app_images', 'external_link'))
コード例 #4
0
def makeLinkView(fsPathString=''):
    """Generate-new-link route."""
    user = g.user
    form = EditLinkForm()
    db = dbGetDatabase()
    boxPath = splitPathString(fsPathString)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    parentBoxPath = boxPath
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    if form.validate_on_submit():
        linkName = secure_filename(form.linkname.data)
        linkTitle = form.linktitle.data
        linkDescription = form.linkdescription.data
        linkTarget = form.linktarget.data
        openInNewWindow = form.openinnewwindow.data
        savingResult = makeLinkInParent(
            db=db,
            user=user,
            parentBox=parentBox,
            date=datetime.now(),
            linkName=linkName,
            linkTitle=linkTitle,
            linkDescription=linkDescription,
            linkTarget=linkTarget,
            linkOptions={
                'open_in_new_window': openInNewWindow,
            },
        )
        return redirect(url_for(
            'lsView',
            lsPathString=fsPathString,
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'New link',
            }],
        )
        form.openinnewwindow.data = True
        return render_template(
            'editlink.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            iconUrl=makeSettingImageUrl(g, 'app_images', 'external_link'),
            pageTitle='New link',
            pageSubtitle='Create a new link in "%s"' %
            (describeBoxTitle(parentBox)),
        )
コード例 #5
0
def preparePickBoxPageView(db,
                           user,
                           callbackUrl,
                           startBox,
                           message,
                           predicate=lambda richFileOrBox: True):
    """
        Prepare a full response for a "select box" view. Boxes are made
        selectable according to a 'predicate' and upon selection the callback
        URL is invokect, with the chosen box path passed as querystring
        parameter 'chosenBoxObjPath'.
    """
    dstBoxTree = collectTreeFromBox(
        db,
        startBox,
        user,
        admitFiles=False,
        fileOrBoxEnricher=lambda richBox: {
            'obj_path': urllib.parse.quote_plus('/'.join(richBox['path'])),
        },
        predicate=predicate,
    )
    #
    maxDepth = getMaxTreeDepth(dstBoxTree)
    colorShadeMap = prepareColorShadeMap(
        g.settings['color']['navigation_colors']['box']['value'],
        g.settings['color']['tree_shade_colors']['shade_treeview_pickbox']
        ['value'],
        numShades=1 + maxDepth,
    )
    #
    return render_template(
        'dirtreeview.html',
        tree=dstBoxTree,
        mode='pick_box',
        object_quoted_path=callbackUrl,
        colorShadeMap=colorShadeMap,
        user=user,
        iconUrl=makeSettingImageUrl(g, 'app_images', 'move'),
        pageTitle='Choose a box',
        pageSubtitle=message,
        actions=None,
        backToUrl=None,
        breadCrumbs=[
            {
                'kind': 'link',
                'target': None,
                'name': 'Move box',
            },
        ],
    )
コード例 #6
0
def userThumbnailView(dummyId, username):
    """Route for access to thumbnail image files based on user name."""
    user = g.user
    db = dbGetDatabase()
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    if user.username == username or userIsAdmin(db, user):
        targetUser = (user if user.username == username else dbGetUser(
            db, username))
        if targetUser.icon_file_id != '':
            filePhysicalPath, filePhysicalName = fileIdToSplitPath(
                targetUser.icon_file_id,
                fileStorageDirectory=fileStorageDirectory,
            )
            return send_from_directory(
                filePhysicalPath,
                filePhysicalName,
                mimetype=targetUser.icon_mime_type,
            )
        else:
            return redirect(makeSettingImageUrl(g, 'user_images', 'user_icon'))
    else:
        return abort(400, 'User has no permission to access this resource.')
コード例 #7
0
def changePasswordUponTicket(db, user, issuer, richTicket, urlRoot):
    """Change-password-ticket route."""
    ticketsByformerAdminsAreProtected = g.settings['behaviour'][
        'behaviour_tickets']['protect_nonadmin_user_password_tickets']['value']
    applicationLongName = g.settings['behaviour']['behaviour_appearance'][
        'application_long_name']['value']
    if not ticketsByformerAdminsAreProtected or userIsAdmin(db, issuer):
        form = generateTicketChangePasswordForm(g.settings)
        if form.validate_on_submit():
            changeeUser = dbGetUser(db, richTicket['metadata']['username'])
            if form.username.data == changeeUser.username:
                #
                newPassword = form.newpassword.data
                minPasswordLength = g.settings['behaviour'][
                    'behaviour_security']['password_min_length']['value']
                if len(form.newpassword.data) < minPasswordLength:
                    print('richTicket ', richTicket)
                    flashMessage(
                        'Info',
                        'Please retry',
                        'New password too short (min. %i characters)' %
                        (minPasswordLength, ),
                    )
                    return redirect(
                        url_for(
                            'redeemTicketView',
                            mode='p',
                            ticketId=richTicket['ticket'].ticket_id,
                            securityCode=richTicket['ticket'].security_code,
                        ))
                else:
                    newUser = User(
                        **({(k if k != 'passwordhash' else 'password'): (
                            v if k != 'passwordhash' else form.newpassword.data
                        )
                            for k, v in changeeUser.asDict().items()}))
                    try:
                        dbPunchRichTicket(db, richTicket, skipCommit=True)
                        dbUpdateUser(db, newUser, user, skipCommit=True)
                        db.commit()
                        # flash a message
                        flashMessage(
                            'Success',
                            'Success',
                            'Password changed. You can now log in to %s' %
                            (applicationLongName, ),
                        )
                        # go to login
                        return redirect(url_for('loginView'))
                    except Exception as e:
                        db.rollback()
                        raise e
            else:
                raise OstracionError('Wrong username provided')
        else:
            pageSubtitle = ('Complete the process by entering your '
                            'new password twice%s') % (
                                '' if richTicket['metadata'].get('message') is
                                None else '. Message on ticket: "%s"' %
                                (richTicket['metadata'].get('message'), ))
            return render_template(
                'userchangepassword.html',
                user=user,
                form=form,
                showOldPasswordField=False,
                mode='ticket',
                breadCrumbs=None,
                pageTitle='Change password',
                pageSubtitle=pageSubtitle,
                iconUrl=makeSettingImageUrl(g, 'admin_images',
                                            'change_password_ticket'),
                backToUrl=url_for('lsView'),
            )
    else:
        raise OstracionError('Ticket not acessible or expired')
コード例 #8
0
def uploadFilesUponTicket(db, user, issuer, richTicket, urlRoot):
    """ Upload-file(s)-upon-ticket route.

        Upload fails if
            1. user banned;
            2. issuer has no upload permission
               (incl. access) on the target box.
    """
    noBandUsrTickets = g.settings['behaviour']['behaviour_tickets'][
        'protect_banned_user_tickets']['value']
    if not noBandUsrTickets or issuer.banned == 0:
        boxPath = richTicket['metadata']['box_path']
        request._onErrorUrl = url_for(
            'lsView',
            lsPathString='/'.join(boxPath[1:]),
        )
        box = getBoxFromPath(db, boxPath[1:], issuer)
        fileStorageDirectory = g.settings['system']['system_directories'][
            'fs_directory']['value']
        if userHasPermission(db, issuer, box.permissions, 'w'):
            # ticket is completely valid: here the form
            # handling (get/post) occurs
            uploadsLeft = (None if richTicket['ticket'].multiplicity is None
                           else (richTicket['ticket'].multiplicity -
                                 richTicket['ticket'].times_redeemed))
            form = UploadMultipleFilesForm()
            if form.validate_on_submit():
                uploadedFiles = [
                    uf for uf in request.files.getlist('files')
                    if uf.filename != ''
                ]
                filesdescription = form.filesdescription.data
                # are there too many files?
                if uploadsLeft is None or len(uploadedFiles) <= uploadsLeft:
                    filesToUpload = [{
                        'box_id':
                        box.box_id,
                        'name':
                        secure_filename(uploadedFile.filename),
                        'description':
                        form.filesdescription.data,
                        'date':
                        datetime.datetime.now(),
                        'fileObject':
                        uploadedFile,
                    } for uploadedFile in uploadedFiles]
                    # we punch the ticket as many times as
                    # there were files provided
                    dbPunchRichTicket(
                        db,
                        richTicket,
                        numPunches=len(filesToUpload),
                    )
                    makeThumbnails = g.settings['behaviour'][
                        'behaviour_appearance']['extract_thumbnails']['value']
                    savingResult = saveAndAnalyseFilesInBox(
                        db=db,
                        files=filesToUpload,
                        parentBox=box,
                        user=issuer,
                        fileStorageDirectory=fileStorageDirectory,
                        thumbnailFormat=('thumbnail'
                                         if makeThumbnails else None),
                    )
                    flashMessage('Success', 'Info', savingResult)
                    return redirect(url_for(
                        'lsView',
                        lsPathString='',
                    ))
                else:
                    request._onErrorUrl = url_for(
                        'redeemTicketView',
                        mode='c',
                        ticketId=richTicket['ticket'].ticket_id,
                        securityCode=richTicket['ticket'].security_code,
                    )
                    raise OstracionError(
                        ('Cannot upload this many files '
                         '(maximum %i allowed)') % uploadsLeft)
            else:
                return render_template(
                    'uploadmultiplefiles.html',
                    form=form,
                    user=user,
                    breadCrumbs=[],
                    pageTitle='Upload file(s)',
                    pageSubtitle='Upload%s files%s' % (
                        ('' if uploadsLeft is None else ' up to %i' %
                         uploadsLeft),
                        ('' if richTicket['metadata'].get('message') is None
                         else ('. Message on ticket: "%s"' %
                               (richTicket['metadata']['message']))),
                    ),
                    iconUrl=makeSettingImageUrl(
                        g,
                        'app_images',
                        ('single_upload' if optionNumberLeq(1, uploadsLeft)
                         else 'multiple_upload'),
                    ),
                )
        else:
            # issuer has no write permission in box
            raise OstracionError('Ticket not acessible or expired')
    else:
        raise OstracionError('Ticket not acessible or expired')
コード例 #9
0
ファイル: boxaccess.py プロジェクト: hemidactylus/ostracion
def fsMoveBoxView(quotedSrcBox):
    """
        Move-box-phase-1 route: where the source box is selected
        (and then in offering the choose-dest-box it is put in the URL
        for calling phase two).
    """
    user = g.user
    db = dbGetDatabase()
    # first we find the box
    bxPathString = urllib.parse.unquote_plus(quotedSrcBox)
    boxPath = splitPathString(bxPathString)
    parentBox = getBoxFromPath(db, boxPath[:-1], user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:-1]),
    )
    box = getBoxFromPath(db, boxPath, user)
    if not canDeleteBox(db, box, parentBox, user):
        raise OstracionWarning('Cannot act on this object')
    # next we prepare the selectable destinations
    rootBox = getRootBox(db)

    def rbPredicate(richBox, _box=box, _srcBox=parentBox):
        _dstBox = richBox['box']
        if _box.parent_id != _dstBox.box_id:
            if all(userHasPermission(db, user, _dstBox.permissions, prm)
                    for prm in {'w', 'c'}):
                if not isNameUnderParentBox(db, _dstBox, _box.box_name):
                    if not isAncestorBoxOf(db, _box, _dstBox):
                        return True
        return False

    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']['box']['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='box_move',
        object_quoted_path=quotedSrcBox,
        colorShadeMap=colorShadeMap,
        user=user,
        iconUrl=makeSettingImageUrl(g, 'app_images', 'move'),
        pageTitle='Select box destination',
        pageSubtitle=('Choose the box to which box "%s" '
                      'shall be moved from "%s"') % (
                            describeBoxTitle(box),
                            describeBoxTitle(parentBox),
                     ),
        actions=None,
        backToUrl=(None
                   if destinationsExist
                   else url_for(
                        'lsView',
                        lsPathString='/'.join(boxPath[1:]))),
        breadCrumbs=makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[
                {
                    'kind': 'link',
                    'target': None,
                    'name': 'Move box',
                }
            ],
        ),
    )
コード例 #10
0
ファイル: boxaccess.py プロジェクト: hemidactylus/ostracion
def makeTicketBoxUploadView(boxPathString=''):
    """Make-upload-ticket (to a box) route."""
    user = g.user
    db = dbGetDatabase()
    boxPath = splitPathString(boxPathString)
    box = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    #
    if userHasPermission(db, user, box.permissions, 'w'):
        #
        pathBCrumbs = makeBreadCrumbs(
            boxPath,
            g,
            appendedItems=[
                {
                    'name': '(create upload ticket)',
                    'kind': 'link',
                    'target': url_for(
                        'makeTicketBoxUploadView',
                        boxPathString=boxPathString,
                    ),
                    'link': False,
                },
            ],
        )
        form = generateFsTicketForm(
            fileModePresent=False,
            settings=g.settings,
        )
        if form.validate_on_submit():
            magicLink = dbMakeUploadTicket(
                db=db,
                ticketName=form.name.data,
                validityHours=transformIfNotEmpty(
                    form.validityhours.data,
                    int,
                ),
                multiplicity=transformIfNotEmpty(
                    form.multiplicity.data,
                    int,
                ),
                ticketMessage=transformIfNotEmpty(
                    form.ticketmessage.data,
                ),
                box=box,
                boxPath=boxPath,
                user=user,
                urlRoot=request.url_root,
                settings=g.settings,
            )
            flashMessage(
                'Success',
                'Done',
                ('Upload ticket generated. Give the recipient '
                 'the following magic link:'),
                pillText=magicLink,
            )
            return redirect(url_for(
                'lsView',
                lsPathString='/'.join(boxPath[1:]),
            ))
        else:
            defaultName = 'Upload-To-%s' % (
                describeBoxName(box)
            )
            form.name.data = applyDefault(form.name.data, defaultName)
            form.ticketmessage.data = applyDefault(
                form.ticketmessage.data,
                'Please, upload files to this box',
            )
            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 upload ticket',
                pageSubtitle=('Recipient(s) of the ticket will be able to '
                              'upload to "%s", without an account, on '
                              'your behalf.') % (
                                    describeBoxTitle(box)
                               ),
                baseMultiplicityCaption='Number of granted file uploads',
                user=user,
                form=form,
                iconUrl=makeSettingImageUrl(g, 'app_images', 'upload_ticket'),
                showFileMode=False,
                breadCrumbs=pathBCrumbs,
            )
        #
    else:
        raise OstracionError('Insufficient permissions')
コード例 #11
0
def loginView():
    """Login view."""
    user = g.user
    db = dbGetDatabase()
    g._onErrorUrl = url_for('loginView')
    if user is not None and user.is_authenticated:
        return redirect(url_for('indexView'))
    form = LoginForm()
    loginProtectionSeconds = int(g.settings['behaviour']['behaviour_security']
                                 ['login_protection_seconds']['value'])
    if form.validate_on_submit():
        #
        loginWaitSeconds = secondsToWaitBeforeLogin(
            db,
            request.remote_addr,
            doWrite=True,
            loginProtectionSeconds=loginProtectionSeconds,
            hashSalt=g.settings['behaviour']['behaviour_security']
            ['ip_addr_hashing_salt']['value'],
        )
        if loginWaitSeconds <= 0:
            #
            qUser = dbGetUser(db, form.username.data)
            if qUser and qUser.checkPassword(form.password.data):
                #
                newUser = User(**qUser.asDict())
                newUser.last_login = datetime.datetime.now()
                dbUpdateUser(db, newUser, qUser)
                #
                login_user(qUser)
                #
                flashMessage(
                    'Success',
                    'Login successful',
                    'welcome, %s!' % (qUser.fullname, ),
                )
                #
                return redirect(url_for('indexView'))
            else:
                g._onErrorUrl = url_for(
                    'loginView',
                    username=form.username.data,
                )
                raise OstracionError('invalid username or password')
        else:
            raise OstracionWarning(
                ('Automated repeated login protection. '
                 'Please wait %i seconds ...') % int(loginWaitSeconds))
    else:
        requestParams = request.args
        form.username.data = applyDefault(
            form.username.data,
            requestParams.get('username', ''),
        )
        appShortName = g.settings['behaviour']['behaviour_appearance'][
            'application_short_name']['value']
        iconUrl = makeSettingImageUrl(g, 'user_images', 'login')
        return render_template(
            'login.html',
            form=form,
            user=user,
            pageTitle=loginTitle(g),
            pageSubtitle=loginSubtitle(g),
            iconUrl=iconUrl,
        )
コード例 #12
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',
            }],
        ),
    )
コード例 #13
0
def quickFindView():
    """Quick (i.e. in-navbar) box- and file-find route."""
    user = g.user
    db = dbGetDatabase()
    form = QuickFindForm()
    #
    if not g.canPerformSearch:
        raise OstracionError('Insufficient permissions')
    # search parameter collection
    searchMode = 'sim_ci'
    searchBoxes = True
    searchFiles = True
    searchLinks = True
    searchInDescription = False
    searchTerm = form.quicktext.data if form.quicktext.data is not None else ''
    options = {
        'mode': searchMode,
        'searchBoxes': searchBoxes,
        'searchFiles': searchFiles,
        'searchLinks': searchLinks,
        'useDescription': searchInDescription,
    }
    # recasting of the above default for the displayed form
    findForm = FindForm()
    findForm.searchMode.data = searchMode
    findForm.searchTypeBoxes.data = searchBoxes
    findForm.searchTypeFiles.data = searchFiles
    findForm.searchTypeLinks.data = searchLinks
    findForm.searchFieldDescription.data = searchInDescription
    findForm.text.data = searchTerm
    #
    initTime = time.time()
    findResults = fsFind(
        db,
        searchTerm,
        user,
        options=options,
    )
    resultsDescription = describeFindResults(findResults)
    elapsed = time.time() - initTime
    #
    return render_template(
        'findform.html',
        user=user,
        form=findForm,
        pageTitle='Search Results',
        pageSubtitle='Search term: "%s"' % searchTerm,
        iconUrl=makeSettingImageUrl(g, 'app_images', 'search'),
        breadCrumbs=[
            {
                'name': 'Tools',
                'type': 'link',
                'target': None,
                'link': False,
            },
            {
                'name': 'Search',
                'type': 'link',
                'target': None,
                'link': False,
            },
        ],
        findResults=findResults,
        resultsDescription=resultsDescription,
        elapsed=elapsed,
        searchTerm=searchTerm,
    )
コード例 #14
0
ファイル: uploads.py プロジェクト: hemidactylus/ostracion
def uploadMultipleFilesView(fsPathString=''):
    """Upload-several-files (to a box) route."""
    user = g.user
    form = UploadMultipleFilesForm()
    db = dbGetDatabase()
    boxPath = splitPathString(fsPathString)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(boxPath[1:]),
    )
    fileStorageDirectory = g.settings['system']['system_directories'][
        'fs_directory']['value']
    parentBoxPath = boxPath
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    #
    if form.validate_on_submit():
        uploadedFiles = [
            uf
            for uf in request.files.getlist('files')
            if uf.filename != ''
        ]
        #
        filesToUpload = [
            {
                'box_id': parentBox.box_id,
                'name': secure_filename(uploadedFile.filename),
                'description': form.filesdescription.data,
                'date': datetime.datetime.now(),
                'fileObject': uploadedFile,
            }
            for uploadedFile in uploadedFiles
        ]
        makeThumbnails = g.settings['behaviour']['behaviour_appearance'][
            'extract_thumbnails']['value']
        savingResult = saveAndAnalyseFilesInBox(
            db=db,
            files=filesToUpload,
            parentBox=parentBox,
            user=user,
            fileStorageDirectory=fileStorageDirectory,
            thumbnailFormat='thumbnail' if makeThumbnails else None,
        )
        flashMessage('Success', 'Info', savingResult)
        return redirect(url_for(
            'lsView',
            lsPathString='/'.join(parentBoxPath[1:]),
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'Multiple upload',
            }],
        )
        return render_template(
            'uploadmultiplefiles.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            pageTitle='Upload new files',
            pageSubtitle='Upload new files to box "%s"' % (
                describeBoxTitle(parentBox)
            ),
            iconUrl=makeSettingImageUrl(g, 'app_images', 'multiple_upload')
        )
コード例 #15
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,
            )
コード例 #16
0
def createUserUponTicket(db, user, issuer, richTicket, urlRoot):
    """User-creation-ticket route."""
    ticketsByformerAdminsAreProtected = g.settings['behaviour'][
        'behaviour_tickets']['protect_nonadmin_user_password_tickets']['value']
    appLongName = g.settings['behaviour']['behaviour_appearance'][
        'application_long_name']['value']
    if not ticketsByformerAdminsAreProtected or userIsAdmin(db, issuer):
        form = generateNewUserForm(g.settings)
        if form.validate_on_submit():
            userDict = {
                'username': form.username.data,
                'fullname': form.fullname.data,
                'email': form.email.data,
                'password': form.password.data,
            }
            if ('username' in richTicket['metadata']
                    and richTicket['metadata']['username'] !=
                    userDict['username']):
                raise RuntimeError(
                    'Detected attempt to escape username set by ticket issuer')
            else:
                # the usename must not exist (relevant if left free in ticket)
                if isUsername(db, userDict['username'], user):
                    if 'username' in richTicket['metadata']:
                        request._onErrorUrl = url_for('lsView')
                    else:
                        request._onErrorUrl = url_for(
                            'redeemTicketView',
                            mode='u',
                            ticketId=ticketId,
                            securityCode=securityCode,
                        )
                    raise OstracionError('Username "%s" exists already' %
                                         userDict['username'])
                else:
                    # we proceed with the user creation proper
                    newUser = User(
                        icon_file_id='',
                        icon_file_id_username=userDict['username'],
                        banned=0,
                        terms_accepted='0',
                        terms_accepted_version='',
                        **userDict,
                    )
                    try:
                        dbPunchRichTicket(db, richTicket, skipCommit=True)
                        dbCreateUser(db, newUser, user)
                        #
                        flashMessage(
                            'Info',
                            'Success',
                            'User created. You can now log in to %s' %
                            (appLongName),
                        )
                        return redirect(url_for('loginView'))
                    except Exception as e:
                        db.rollback()
                        raise e
        else:
            form.username.data = applyDefault(
                form.username.data,
                richTicket['metadata'].get('username', ''),
            )
            form.fullname.data = applyDefault(
                form.fullname.data,
                richTicket['metadata'].get('fullname', ''),
            )
            form.email.data = applyDefault(
                form.email.data,
                richTicket['metadata'].get('email', ''),
            )
            return render_template(
                'newuser.html',
                form=form,
                user=user,
                pageTitle='Create user',
                pageSubtitle='Create your user account on %s%s' % (
                    appLongName,
                    ('' if richTicket['metadata'].get('message') is None else
                     '. Message on ticket: "%s"' %
                     (richTicket['metadata']['message'])),
                ),
                iconUrl=makeSettingImageUrl(g, 'user_images', 'user_icon'),
                lockUsernameField='username' in richTicket['metadata'],
            )
    else:
        raise OstracionError('Ticket not acessible or expired')
        return redirect(url_for('lsView'))
コード例 #17
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)
コード例 #18
0
ファイル: boxaccess.py プロジェクト: hemidactylus/ostracion
def makeBoxView(parentBoxPathString=''):
    """MKBOX-in-a-box- route."""
    user = g.user
    form = makeMakeBoxForm('Create')()
    db = dbGetDatabase()
    parentBoxPath = splitPathString(parentBoxPathString)
    parentBox = getBoxFromPath(db, parentBoxPath, user)
    boxNiceName = describeBoxTitle(parentBox)
    request._onErrorUrl = url_for(
        'lsView',
        lsPathString='/'.join(parentBoxPath),
    )
    if form.validate_on_submit():
        #
        boxName = form.boxname.data
        boxDescription = form.boxdescription.data
        boxTitle = form.boxtitle.data
        #
        newBox = Box(
            box_name=boxName,
            title=boxTitle,
            description=boxDescription,
            icon_file_id='',
            nature='box',
            parent_id=parentBox.box_id,
            date=datetime.now(),
            creator_username=user.username,
            icon_file_id_username=user.username,
            metadata_username=user.username,
        )
        makeBoxInParent(db, parentBox, newBox, user, skipCommit=True)
        if parentBox.box_id == '':
            # the new box is a direct child of root:
            # act according to the localhost-mode policy setting
            rootChildAnonPerms = g.settings['behaviour'][
                'behaviour_permissions'][
                'rootchild_box_anonymous_permissions']['value']
            rcPermSet = {
                k: 1 if rootChildAnonPerms[i] != '_' else 0
                for i, k in enumerate('rwc')
            }
            # the above is a bit of a hack which parses the char
            # of the setting 'r__', 'rwc', ...
            rootChildBRP = BoxRolePermission(
                box_id=newBox.box_id,
                role_class='system',
                role_id='anonymous',
                **rcPermSet,
            )
            dbInsertBoxRolePermission(
                db,
                rootChildBRP,
                user,
                skipCommit=True,
            )
        #
        db.commit()
        additionalLsItems = [boxName]
        #
        return redirect(url_for(
            'lsView',
            lsPathString='/'.join(parentBoxPath[1:] + additionalLsItems),
        ))
    else:
        pathBCrumbs = makeBreadCrumbs(
            parentBoxPath,
            g,
            appendedItems=[{
                'kind': 'link',
                'target': None,
                'name': 'Make box',
            }],
        )
        return render_template(
            'makebox.html',
            form=form,
            user=user,
            breadCrumbs=pathBCrumbs,
            iconUrl=makeSettingImageUrl(g, 'app_images', 'standard_box'),
            pageTitle='Create box in "%s"' % boxNiceName,
            pageSubtitle='Name and title are mandatory',
        )
コード例 #19
0
ファイル: boxaccess.py プロジェクト: hemidactylus/ostracion
def makeTicketBoxGalleryView(boxPathString=''):
    """Make-gallery-ticket-of-box route."""
    user = g.user
    db = dbGetDatabase()
    boxPath = splitPathString(boxPathString)
    box = getBoxFromPath(db, boxPath, user)
    request._onErrorUrl = url_for('lsView', lsPathString='/'.join(boxPath[1:]))
    #
    pathBCrumbs = makeBreadCrumbs(
        boxPath,
        g,
        appendedItems=[
            {
                'name': '(create gallery ticket)',
                'kind': 'link',
                'target': url_for(
                    'makeTicketBoxGalleryView',
                    boxPathString=boxPathString,
                ),
                'link': False,
            },
        ],
    )
    form = generateFsTicketForm(
        fileModePresent=False,
        settings=g.settings,
    )
    if form.validate_on_submit():
        magicLink = dbMakeGalleryTicket(
            db=db,
            ticketName=form.name.data,
            validityHours=transformIfNotEmpty(
                form.validityhours.data,
                int
            ),
            multiplicity=transformIfNotEmpty(
                form.multiplicity.data,
                int
            ),
            ticketMessage=transformIfNotEmpty(
                form.ticketmessage.data
            ),
            box=box,
            boxPath=boxPath,
            user=user,
            urlRoot=request.url_root,
            settings=g.settings,
        )
        flashMessage(
            'Success',
            'Done',
            ('Gallery ticket generated. Give the recipient '
             'the following magic link:'),
            pillText=magicLink,
        )
        return redirect(url_for(
            'lsView',
            lsPathString='/'.join(boxPath[1:]),
        ))
    else:
        defaultName = 'Gallery-View-%s' % describeBoxName(box)
        form.name.data = applyDefault(form.name.data, defaultName)
        form.ticketmessage.data = applyDefault(
            form.ticketmessage.data,
            'Please, look at this gallery',
        )
        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 gallery-view ticket',
            pageSubtitle=('Recipient(s) of the ticket will be able to view '
                          'files (and not contained boxes) in "%s", without '
                          'an account, as a gallery. If setting a number of '
                          'accesses, keep in mind that every single-file view'
                          ' counts toward the total accesses.') % (
                describeBoxTitle(box)
            ),
            baseMultiplicityCaption='Number of granted accesses',
            user=user,
            form=form,
            iconUrl=makeSettingImageUrl(g, 'app_images', 'gallery_ticket'),
            showFileMode=False,
            breadCrumbs=pathBCrumbs,
        )
コード例 #20
0
def before_request():
    """ Preparation of globally-accessible info for all views,
        handling of special post-install situations and of banned users
        and logged-in-only setups.
    """
    db = dbGetDatabase()
    g.user = current_user
    g.settings = dbLoadAllSettings(db, g.user)
    g.applicationLogoUrl = makeSettingImageUrl(
        g,
        'ostracion_images',
        'navbar_logo',
    )
    #
    g.canPerformSearch = isUserWithinPermissionCircle(
        db,
        g.user,
        g.settings['behaviour']['search']['search_access']['value'],
    )
    g.quickFindForm = QuickFindForm()
    g.canShowTreeView = isUserWithinPermissionCircle(
        db,
        g.user,
        g.settings['behaviour']['search']['tree_view_access']['value'],
    )
    # task lists - must happen after the above (which set access flags)
    g.availableApps = selectAvailableApps(db, g.user, g)
    g.availableInfoItems = selectAvailableInfoItems(db, g.user, g)
    g.availableTools = selectAvailableTools(db, g.user, g)
    #
    if g.user.is_authenticated:
        g.user.setRoles(list(dbGetUserRoles(db, g.user)))
        if g.user.banned:
            flashMessage(
                'Warning',
                'Warning',
                ('Your user is momentarily banned. '
                 'Please continue as anonymous'),
            )
            logout_user()
    # handling of first-time post-install forced steps
    dirsSetUp = g.settings['managed']['post_install_finalisations'][
        'directories_set_up']['value']
    if (not dirsSetUp
            and request.endpoint not in endpointsWithoutAppInitRerouting):
        if g.user.is_authenticated and userIsAdmin(db, g.user):
            flashMessage(
                'Warning',
                'Action required',
                ('Please review carefully the following directory settings '
                 'to make the application function. Changing them later, '
                 'when material is uploaded, is a disruptive operation.'),
            )
            return redirect(
                url_for('adminHomeSettingsGenericView',
                        settingType='system_settings'))
        else:
            if g.user.is_authenticated:
                logout_user()
            flashMessage(
                'Warning',
                'Action required',
                ('To finalise installation/make the application function '
                 'properly, an administrator should log in and '
                 'complete the setup'),
            )
            return redirect(url_for('loginView'))
    else:
        # we care about reviewing the settings only if the dirs are OK
        if g.user.is_authenticated and userIsAdmin(db, g.user):
            if request.endpoint not in endpointsWithoutAppInitRerouting:
                settingsReviewed = g.settings['managed'][
                    'post_install_finalisations']['settings_reviewed']['value']
                if not settingsReviewed:
                    flashMessage(
                        'Warning',
                        'Action required',
                        ('Please carefully review the following application '
                         'behaviour settings before opening the service '
                         'to users (anyway, these settings can be '
                         'changed at any time).'),
                    )
                    return redirect(
                        url_for('adminHomeSettingsGenericView',
                                settingType='behaviour'))
    # we take care of terms-and-conditions acceptance here
    if request.endpoint not in endpointsWithoutTermAcceptanceBlocking:
        usersMustAbideByTOS = g.settings['terms']['terms']['terms_must_agree'][
            'value']
        anonymousMustAbideByTOS = g.settings['terms']['terms'][
            'terms_must_agree_anonymous']['value']
        currentTermVersion = g.settings['terms']['terms']['terms_version'][
            'value']
        #
        if g.user.is_authenticated:
            mustAbideByTOS = usersMustAbideByTOS
            typeOfUsers = 'Users'
            storedTermsVersion = g.user.terms_accepted_version
            storedTermsAcceptance = safeInt(
                g.user.terms_accepted,
                default=None,
            )
        else:
            mustAbideByTOS = anonymousMustAbideByTOS
            typeOfUsers = 'Visitors'
            storedTermsVersion = request.cookies.get('termsAcceptedVersion')
            storedTermsAcceptance = safeInt(
                request.cookies.get('termsAccepted'),
                default=None,
            )
        #
        if storedTermsVersion == currentTermVersion:
            thisVersionAcceptance = storedTermsAcceptance
        else:
            thisVersionAcceptance = None
        #
        if thisVersionAcceptance is None:
            canContinueTermwise = not mustAbideByTOS
        elif thisVersionAcceptance == 0:
            # explicit not-acceptance
            canContinueTermwise = False
        else:
            # positive updated acceptance
            canContinueTermwise = True
        #
        if not canContinueTermwise:
            quotedTravelToPath = urllib.parse.quote_plus(request.full_path)
            flashMessage(
                'Info',
                'Action required',
                ('%s must review the Terms and Conditions'
                 ' before accessing the site.') % typeOfUsers,
            )
            return redirect(
                url_for(
                    'termsView',
                    showAgreementButtons='y',
                    travelTo=quotedTravelToPath,
                ))

    # here the ordinary flow is resumed
    if g.settings['behaviour']['behaviour_permissions'][
            'logged_in_users_only']['value']:
        if (not g.user.is_authenticated and request.endpoint
                not in endpointsWithoutInviteOnlyBlocking):
            return redirect(url_for('loginView'))