Exemple #1
0
    def delete(self, permission_id):
        db_session = data_engine.db_get_session()
        db_commit = False
        try:
            fp = data_engine.get_object(
                FolderPermission,
                permission_id,
                _db_session=db_session
            )
            if fp is None:
                raise DoesNotExistError(str(permission_id))
            try:
                data_engine.delete_folder_permission(
                    fp, _db_session=db_session, _commit=False
                )
            except ValueError as e:
                raise ParameterError(str(e))

            db_commit = True
            return make_api_success_response()
        finally:
            if db_commit:
                db_session.commit()
                permissions_engine.reset()
            else:
                db_session.rollback()
            db_session.close()
Exemple #2
0
 def post(self):
     # Require folios or admin_folios permission to create a portfolio
     permissions_engine.ensure_permitted(SystemPermissions.PERMIT_FOLIOS,
                                         get_session_user())
     db_session = data_engine.db_get_session()
     try:
         params = self._get_validated_object_parameters(request.form)
         folio = Folio(params['human_id'] or Folio.create_human_id(),
                       params['name'], params['description'],
                       get_session_user())
         self._set_permissions(folio, params, db_session)
         data_engine.create_portfolio(
             folio,
             get_session_user(),
             _db_session=db_session,
             _commit=True  # fail here if human_id not unique
         )
         # Return a clean object the same as for get(id)
         folio = data_engine.get_portfolio(folio.id,
                                           load_images=True,
                                           load_history=True)
         folio = _prep_folio_object(folio)
         return make_api_success_response(
             object_to_dict(folio, _omit_fields))
     finally:
         db_session.close()
Exemple #3
0
def trace_permissions():
    embed = request.args.get('embed', '')
    user_id = request.args.get('user', '')
    folder_path = request.args.get('path', '')
    if folder_path == '':
        folder_path = os.path.sep

    folder = None
    user = None
    users = []
    user_has_admin = False
    trace = None
    err_msg = None
    db_session = data_engine.db_get_session()
    try:
        # Get folder and selected user info
        # User can be None for an anonymous user
        user_id = parse_int(user_id)
        if user_id != 0:
            user = data_engine.get_user(user_id, _db_session=db_session)
            if user is None:
                raise DoesNotExistError('This user no longer exists')
        folder = data_engine.get_folder(folder_path=folder_path,
                                        _db_session=db_session)
        if folder is None or folder.status == Folder.STATUS_DELETED:
            raise DoesNotExistError('This folder no longer exists')

        # Get users list
        users = data_engine.list_users(status=User.STATUS_ACTIVE,
                                       order_field=User.username,
                                       _db_session=db_session)

        # Get the folder+user traced permissions
        trace = permissions_engine._trace_folder_permissions(folder, user)

        # Flag on the UI if the user has admin
        for gdict in trace['groups']:
            gperms = gdict['group'].permissions
            if gperms.admin_files or gperms.admin_all:
                user_has_admin = True
                break

    except Exception as e:
        log_security_error(e, request)
        err_msg = safe_error_str(e)
    finally:
        try:
            return render_template(
                'admin_trace_permissions.html',
                embed=embed,
                folder=folder,
                folder_is_root=folder.is_root() if folder else False,
                user=user,
                user_list=users,
                trace=trace,
                user_has_admin=user_has_admin,
                err_msg=err_msg,
                GROUP_ID_PUBLIC=Group.ID_PUBLIC)
        finally:
            db_session.close()
Exemple #4
0
    def post(self):
        params = self._get_validated_object_parameters(request.form)
        db_session = data_engine.db_get_session()
        db_commit = False
        try:
            db_group = data_engine.get_group(params['group_id'],
                                             _db_session=db_session)
            if db_group is None:
                raise DoesNotExistError(str(params['group_id']))
            db_folder = data_engine.get_folder(params['folder_id'],
                                               _db_session=db_session)
            if db_folder is None:
                raise DoesNotExistError(str(params['folder_id']))

            # This commits (needed for refresh to get the new ID)
            fp = FolderPermission(db_folder, db_group, params['access'])
            fp = data_engine.save_object(fp,
                                         refresh=True,
                                         _db_session=db_session,
                                         _commit=True)
            db_commit = True
            return make_api_success_response(object_to_dict(fp))
        finally:
            try:
                if db_commit:
                    db_session.commit()
                    permissions_engine.reset_folder_permissions()
                else:
                    db_session.rollback()
            finally:
                db_session.close()
Exemple #5
0
 def delete(self, folio_id, image_id):
     db_session = data_engine.db_get_session()
     try:
         folio_image = data_engine.get_portfolio_image(
             AttrObject(id=folio_id),
             AttrObject(id=image_id),
             _db_session=db_session)
         if folio_image is None:
             raise DoesNotExistError(str(folio_id) + '/' + str(image_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio_image.portfolio, FolioPermission.ACCESS_EDIT,
             get_session_user())
         # Add history first so that we only commit once at the end
         folio = folio_image.portfolio
         data_engine.add_portfolio_history(folio,
                                           get_session_user(),
                                           FolioHistory.ACTION_IMAGE_CHANGE,
                                           '%s removed' %
                                           folio_image.image.src,
                                           _db_session=db_session,
                                           _commit=False)
         # Flag that exported zips will be out of date
         folio.last_updated = datetime.utcnow()
         # Delete the image from the portfolio and commit changes
         data_engine.delete_object(folio_image,
                                   _db_session=db_session,
                                   _commit=True)
         return make_api_success_response()
     finally:
         db_session.close()
Exemple #6
0
 def delete(self, folio_id, export_id):
     db_session = data_engine.db_get_session()
     try:
         # Get the portfolio
         folio = data_engine.get_portfolio(folio_id, _db_session=db_session)
         if folio is None:
             raise DoesNotExistError(str(folio_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio, FolioPermission.ACCESS_EDIT, get_session_user())
         # Get the single portfolio-export
         folio_export = data_engine.get_object(FolioExport,
                                               export_id,
                                               _db_session=db_session)
         if folio_export is None:
             raise DoesNotExistError(str(export_id))
         if folio_export.folio_id != folio_id:
             raise ParameterError(
                 'export ID %d does not belong to portfolio ID %d' %
                 (export_id, folio_id))
         # Delete it and the export files
         delete_portfolio_export(folio_export,
                                 get_session_user(),
                                 'Deleted: ' + folio_export.describe(True),
                                 _db_session=db_session)
         return make_api_success_response()
     finally:
         db_session.close()
Exemple #7
0
    def delete(self, permission_id):
        db_session = data_engine.db_get_session()
        db_commit = False
        try:
            fp = data_engine.get_object(FolderPermission,
                                        permission_id,
                                        _db_session=db_session)
            if fp is None:
                raise DoesNotExistError(str(permission_id))
            try:
                data_engine.delete_folder_permission(fp,
                                                     _db_session=db_session,
                                                     _commit=False)
            except ValueError as e:
                raise ParameterError(str(e))

            db_commit = True
            return make_api_success_response()
        finally:
            if db_commit:
                db_session.commit()
                permissions_engine.reset_folder_permissions()
            else:
                db_session.rollback()
            db_session.close()
Exemple #8
0
 def get(self, folio_id, image_id=None):
     if image_id is None:
         # List images in the portfolio
         folio = data_engine.get_portfolio(folio_id, load_images=True)
         if folio is None:
             raise DoesNotExistError(str(folio_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio, FolioPermission.ACCESS_VIEW, get_session_user())
         image_list = [_prep_folioimage_object(fi) for fi in folio.images]
         return make_api_success_response(
             object_to_dict_list(image_list, _omit_fields))
     else:
         # Get a single portfolio-image
         db_session = data_engine.db_get_session()
         try:
             folio_image = data_engine.get_portfolio_image(
                 AttrObject(id=folio_id),
                 AttrObject(id=image_id),
                 _db_session=db_session)
             if folio_image is None:
                 raise DoesNotExistError(
                     str(folio_id) + '/' + str(image_id))
             # Check permissions
             permissions_engine.ensure_portfolio_permitted(
                 folio_image.portfolio, FolioPermission.ACCESS_VIEW,
                 get_session_user())
             return make_api_success_response(
                 object_to_dict(_prep_folioimage_object(folio_image),
                                _omit_fields + ['portfolio']))
         finally:
             db_session.close()
Exemple #9
0
    def post(self):
        params = self._get_validated_object_parameters(request.form)
        db_session = data_engine.db_get_session()
        db_commit = False
        try:
            db_group = data_engine.get_group(params['group_id'], _db_session=db_session)
            if db_group is None:
                raise DoesNotExistError(str(params['group_id']))
            db_folder = data_engine.get_folder(params['folder_id'], _db_session=db_session)
            if db_folder is None:
                raise DoesNotExistError(str(params['folder_id']))

            # This commits (needed for refresh to get the new ID)
            fp = FolderPermission(db_folder, db_group, params['access'])
            fp = data_engine.save_object(
                fp, refresh=True, _db_session=db_session, _commit=True
            )
            db_commit = True
            return make_api_success_response(object_to_dict(fp))
        finally:
            try:
                if db_commit:
                    db_session.commit()
                    permissions_engine.reset()
                else:
                    db_session.rollback()
            finally:
                db_session.close()
Exemple #10
0
def delete_portfolio_export(folio_export,
                            history_user,
                            history_info,
                            _db_session=None):
    """
    Deletes a portfolio export record and the associated zip file (if it exists),
    and adds an audit trail entry for the parent portfolio. If you supply a
    database session it will be committed before the zip file is deleted, so
    that files are only deleted once the database operations are known to have
    worked.

    Raises a ServerTooBusyError if the export is still in progress.
    Raises an OSError if the zip file or directory cannot be deleted.
    """
    db_session = _db_session or data_engine.db_get_session()
    try:
        # Ensure we can access folio_export.portfolio
        if not data_engine.object_in_session(folio_export, db_session):
            folio_export = data_engine.get_object(FolioExport,
                                                  folio_export.id,
                                                  _db_session=db_session)

        # Check whether the export task is running
        if folio_export.task_id:
            task = task_engine.get_task(folio_export.task_id,
                                        _db_session=db_session)
            if (task and task.status == Task.STATUS_ACTIVE) or (
                    task and task.status == Task.STATUS_PENDING
                    and not task_engine.cancel_task(task)):
                raise ServerTooBusyError(
                    'this export is currently in progress, wait a while then try again'
                )

        # Delete and add history in one commit
        data_engine.add_portfolio_history(folio_export.portfolio,
                                          history_user,
                                          FolioHistory.ACTION_UNPUBLISHED,
                                          history_info,
                                          _db_session=db_session,
                                          _commit=False)
        data_engine.delete_object(folio_export,
                                  _db_session=db_session,
                                  _commit=True)
        # If we got this far the database delete worked and we now need to
        # delete the exported zip file
        zip_rel_path = get_portfolio_export_file_path(folio_export)
        if folio_export.filename:
            delete_file(zip_rel_path)
        # And if the zip directory is now empty, delete the directory too
        zip_rel_dir = get_portfolio_directory(folio_export.portfolio)
        if path_exists(zip_rel_dir, require_directory=True):
            zips_count = count_files(zip_rel_dir, recurse=False)
            if zips_count[0] == 0:
                delete_dir(zip_rel_dir)
    finally:
        if not _db_session:
            db_session.close()
Exemple #11
0
def folder_permissions():
    folder_path = request.args.get('path', '')
    if folder_path == '':
        folder_path = os.path.sep

    group_id = request.args.get('group', '')
    if group_id == '':
        group_id = Group.ID_PUBLIC

    group = None
    folder = None
    current_perms = None
    groups = []
    err_msg = None
    db_session = data_engine.db_get_session()
    try:
        # Get folder and group info
        group = data_engine.get_group(group_id, _db_session=db_session)
        if group is None:
            raise DoesNotExistError('This group no longer exists')
        folder = data_engine.get_folder(folder_path=folder_path, _db_session=db_session)
        if folder is None or folder.status == Folder.STATUS_DELETED:
            raise DoesNotExistError('This folder no longer exists')

        # Get groups list
        groups = data_engine.list_objects(Group, Group.name, _db_session=db_session)

        # Get the current permissions for the folder+group, which can be None.
        # Note that permissions_manager might fall back to the Public group if
        # this is None, but to keep the admin manageable we're going to deal
        # only with folder inheritance, not group inheritance too.
        current_perms = data_engine.get_nearest_folder_permission(
            folder, group,
            _load_nearest_folder=True,
            _db_session=db_session
        )
    except Exception as e:
        log_security_error(e, request)
        err_msg = str(e)
    finally:
        try:
            return render_template(
                'admin_folder_permissions.html',
                group=group,
                folder=folder,
                folder_is_root=folder.is_root() if folder else False,
                current_permissions=current_perms,
                group_list=groups,
                err_msg=err_msg,
                GROUP_ID_PUBLIC=Group.ID_PUBLIC,
                GROUP_ID_EVERYONE=Group.ID_EVERYONE
            )
        finally:
            db_session.close()
Exemple #12
0
def folder_permissions():
    folder_path = request.args.get('path', '')
    if folder_path == '':
        folder_path = os.path.sep

    group_id = request.args.get('group', '')
    if group_id == '':
        group_id = Group.ID_PUBLIC

    group = None
    folder = None
    current_perms = None
    groups = []
    err_msg = None
    db_session = data_engine.db_get_session()
    try:
        # Get folder and group info
        group = data_engine.get_group(group_id, _db_session=db_session)
        if group is None:
            raise DoesNotExistError('This group no longer exists')
        folder = data_engine.get_folder(folder_path=folder_path,
                                        _db_session=db_session)
        if folder is None or folder.status == Folder.STATUS_DELETED:
            raise DoesNotExistError('This folder no longer exists')

        # Get groups list
        groups = data_engine.list_objects(Group,
                                          Group.name,
                                          _db_session=db_session)

        # Get the current permissions for the folder+group, which can be None.
        # Note that permissions_manager might fall back to the Public group if
        # this is None, but to keep the admin manageable we're going to deal
        # only with folder inheritance, not group inheritance too.
        current_perms = data_engine.get_nearest_folder_permission(
            folder, group, _load_nearest_folder=True, _db_session=db_session)
    except Exception as e:
        log_security_error(e, request)
        err_msg = safe_error_str(e)
    finally:
        try:
            return render_template(
                'admin_folder_permissions.html',
                group=group,
                folder=folder,
                folder_is_root=folder.is_root() if folder else False,
                current_permissions=current_perms,
                group_list=groups,
                err_msg=err_msg,
                GROUP_ID_PUBLIC=Group.ID_PUBLIC,
                GROUP_ID_EVERYONE=Group.ID_EVERYONE)
        finally:
            db_session.close()
Exemple #13
0
 def post(self, folio_id):
     db_session = data_engine.db_get_session()
     try:
         # Get the portfolio
         folio = data_engine.get_portfolio(folio_id, _db_session=db_session)
         if folio is None:
             raise DoesNotExistError(str(folio_id))
         # Check portfolio permissions
         permissions_engine.ensure_portfolio_permitted(
             folio, FolioPermission.ACCESS_EDIT, get_session_user())
         # Get the image by either ID or src
         params = self._get_validated_object_parameters(request.form, True)
         if 'image_id' in params:
             image = data_engine.get_image(params['image_id'],
                                           _db_session=db_session)
             if image is None:
                 raise DoesNotExistError(str(params['image_id']))
         else:
             image = auto_sync_file(params['image_src'],
                                    data_engine,
                                    task_engine,
                                    anon_history=True,
                                    burst_pdf=False,
                                    _db_session=db_session)
             if image is None or image.status == Image.STATUS_DELETED:
                 raise DoesNotExistError(params['image_src'])
         # Check image permissions
         permissions_engine.ensure_folder_permitted(
             image.folder, FolderPermission.ACCESS_VIEW, get_session_user(),
             False)
         # Add history first so that we only commit once at the end
         data_engine.add_portfolio_history(folio,
                                           get_session_user(),
                                           FolioHistory.ACTION_IMAGE_CHANGE,
                                           '%s added' % image.src,
                                           _db_session=db_session,
                                           _commit=False)
         # Flag that exported zips are now out of date
         folio.last_updated = datetime.utcnow()
         # Add the image and commit changes
         db_folio_image = data_engine.save_object(FolioImage(
             folio, image, params['image_parameters'], params['filename'],
             params['index']),
                                                  refresh=True,
                                                  _db_session=db_session,
                                                  _commit=True)
         return make_api_success_response(
             object_to_dict(_prep_folioimage_object(db_folio_image),
                            _omit_fields + ['portfolio']))
     finally:
         db_session.close()
Exemple #14
0
 def put(self, folio_id):
     db_session = data_engine.db_get_session()
     try:
         # Get portfolio
         folio = data_engine.get_portfolio(folio_id, _db_session=db_session)
         if folio is None:
             raise DoesNotExistError(str(folio_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio, FolioPermission.ACCESS_EDIT, get_session_user())
         # Update the object
         params = self._get_validated_object_parameters(request.form)
         permissions_changed = self._set_permissions(
             folio, params, db_session)
         changes = []
         if params['human_id'] != folio.human_id:
             changes.append('short URL changed')
         if params['name'] != folio.name:
             changes.append('name changed')
         if params['description'] != folio.description:
             changes.append('description changed')
         if permissions_changed:
             changes.append('permissions changed')
         folio.human_id = params['human_id'] or Folio.create_human_id()
         folio.name = params['name']
         folio.description = params['description']
         # Note: folio.last_updated is only for image changes
         #       (to know when to invalidate the exported zips)
         data_engine.add_portfolio_history(folio,
                                           get_session_user(),
                                           FolioHistory.ACTION_EDITED,
                                           ', '.join(changes).capitalize(),
                                           _db_session=db_session,
                                           _commit=False)
         data_engine.save_object(
             folio,
             _db_session=db_session,
             _commit=True  # fail here if human_id not unique
         )
         if permissions_changed:
             permissions_engine.reset_portfolio_permissions()
         # Return a clean object the same as for get(id)
         folio = data_engine.get_portfolio(folio.id,
                                           load_images=True,
                                           load_history=True)
         folio = _prep_folio_object(folio)
         return make_api_success_response(
             object_to_dict(folio, _omit_fields))
     finally:
         db_session.close()
Exemple #15
0
 def put(self, folio_id, image_id):
     db_session = data_engine.db_get_session()
     try:
         folio_image = data_engine.get_portfolio_image(
             AttrObject(id=folio_id),
             AttrObject(id=image_id),
             _db_session=db_session)
         if folio_image is None:
             raise DoesNotExistError(str(folio_id) + '/' + str(image_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio_image.portfolio, FolioPermission.ACCESS_EDIT,
             get_session_user())
         # Update the object with any/all parameters that were passed in
         params = self._get_validated_object_parameters(request.form, False)
         changes = []
         affects_zips = False
         if (params['image_parameters'] is not None
                 and params['image_parameters'] != folio_image.parameters):
             folio_image.parameters = params['image_parameters']
             changes.append('image attributes changed')
             affects_zips = True
         if (params['filename'] is not None
                 and params['filename'] != folio_image.filename):
             folio_image.filename = params['filename']
             changes.append('filename changed')
             affects_zips = True
         if (params['index'] is not None
                 and params['index'] != folio_image.order_num):
             folio_image.order_num = params['index']
             changes.append('set as position %d' % (params['index'] + 1))
         if changes:
             # Flag if exported zips will be out of date
             if affects_zips:
                 folio_image.portfolio.last_updated = datetime.utcnow()
             # Add history and commit changes
             data_engine.add_portfolio_history(
                 folio_image.portfolio,
                 get_session_user(),
                 FolioHistory.ACTION_IMAGE_CHANGE,
                 '%s updated: %s' %
                 (folio_image.image.src, ', '.join(changes)),
                 _db_session=db_session,
                 _commit=True)
         return make_api_success_response(
             object_to_dict(_prep_folioimage_object(folio_image),
                            _omit_fields + ['portfolio']))
     finally:
         db_session.close()
Exemple #16
0
 def post(self, folio_id):
     db_session = data_engine.db_get_session()
     try:
         # Get the portfolio
         folio = data_engine.get_portfolio(folio_id, _db_session=db_session)
         if folio is None:
             raise DoesNotExistError(str(folio_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio, FolioPermission.ACCESS_EDIT, get_session_user())
         # Block the export now if it would create an empty zip file
         if len(folio.images) == 0:
             raise ParameterError(
                 'this portfolio is empty and cannot be published')
         # Create a folio-export record and start the export as a background task
         params = self._get_validated_object_parameters(request.form)
         folio_export = FolioExport(folio, params['description'],
                                    params['originals'],
                                    params['image_parameters'],
                                    params['expiry_time'])
         data_engine.add_portfolio_history(folio,
                                           get_session_user(),
                                           FolioHistory.ACTION_PUBLISHED,
                                           folio_export.describe(True),
                                           _db_session=db_session,
                                           _commit=False)
         folio_export = data_engine.save_object(folio_export,
                                                refresh=True,
                                                _db_session=db_session,
                                                _commit=True)
         export_task = task_engine.add_task(
             get_session_user(), 'Export portfolio %d / export %d' %
             (folio.id, folio_export.id), 'export_portfolio', {
                 'export_id': folio_export.id,
                 'ignore_errors': False
             }, Task.PRIORITY_NORMAL, 'info', 'error', 60)
         # Update and return the folio-export record with the task ID
         folio_export.task_id = export_task.id
         data_engine.save_object(folio_export,
                                 _db_session=db_session,
                                 _commit=True)
         return make_api_success_response(object_to_dict(
             _prep_folioexport_object(folio, folio_export),
             _omit_fields + ['portfolio']),
                                          task_accepted=True)
     finally:
         db_session.close()
Exemple #17
0
def delete_image_ids():
    try:
        from imageserver.flask_app import cache_engine, data_engine
        from imageserver import models
        log('Deleting cached image IDs')
        dbs = data_engine.db_get_session()
        try:
            for src in dbs.query(models.Image.src).all():
                cache_key = data_engine._get_id_cache_key(src[0])
                cache_engine.raw_delete(cache_key)
                print '.',
        finally:
            dbs.close()
        log('Done')
        return RETURN_OK
    except Exception as e:
        error(str(e))
Exemple #18
0
def delete_image_ids():
    try:
        from imageserver.flask_app import cache_engine, data_engine
        from imageserver import models
        log('Deleting cached image IDs')
        dbs = data_engine.db_get_session()
        try:
            for src in dbs.query(models.Image.src).all():
                cache_key = data_engine._get_id_cache_key(src[0])
                cache_engine.raw_delete(cache_key)
                print('.', end=' ')
        finally:
            dbs.close()
        log('Done')
        return RETURN_OK
    except Exception as e:
        error(str(e))
Exemple #19
0
 def put(self, folio_id, image_id):
     db_session = data_engine.db_get_session()
     try:
         # Get data
         folio_image = data_engine.get_portfolio_image(
             AttrObject(id=folio_id),
             AttrObject(id=image_id),
             _db_session=db_session)
         if folio_image is None:
             raise DoesNotExistError(str(folio_id) + '/' + str(image_id))
         # Check permissions
         permissions_engine.ensure_portfolio_permitted(
             folio_image.portfolio, FolioPermission.ACCESS_EDIT,
             get_session_user())
         # Update the portfolio
         params = self._get_validated_object_parameters(request.form)
         chd_folio_image = data_engine.reorder_portfolio(
             folio_image, params['index'])
         data_engine.add_portfolio_history(
             folio_image.portfolio,
             get_session_user(),
             FolioHistory.ACTION_IMAGE_CHANGE,
             '%s moved to position %d' %
             (folio_image.image.src, chd_folio_image.order_num + 1),
             _db_session=db_session,
             _commit=True)
         # Return the updated image list
         db_session.expire(folio_image)
         folio = data_engine.get_portfolio(folio_id,
                                           load_images=True,
                                           _db_session=db_session)
         image_list = [_prep_folioimage_object(fi) for fi in folio.images]
         return make_api_success_response(
             object_to_dict_list(image_list, _omit_fields + ['portfolio']))
     finally:
         db_session.close()
Exemple #20
0
def topten():
    # Get parameters
    days = request.args.get('days', '1')
    limit = request.args.get('number', '10')
    data_type = request.args.get('data_type', '2')
    try:
        results = []
        db_session = data_engine.db_get_session()
        try:
            # Convert params to ints
            days = parse_int(days)
            limit = parse_int(limit)
            data_type = parse_int(data_type)

            # Set options
            if days < 1:
                days = 1
            if days > 30:
                days = 30
            if limit < 10:
                limit = 10
            if limit > 100:
                limit = 100

            if data_type == 1:
                order = '-total_requests'
            elif data_type == 2:
                order = '-total_views'
            elif data_type == 3:
                order = '-total_cached_views'
            elif data_type == 4:
                order = '-total_downloads'
            elif data_type == 5:
                order = '-total_bytes'
            elif data_type == 6:
                order = '-total_seconds'
            elif data_type == 7:
                order = '-max_seconds'
            else:
                raise ValueError('Invalid data_type %d' % data_type)

            # Get initial stats
            top_stats = data_engine.summarise_image_stats(
                datetime.utcnow() - timedelta(days=days),
                datetime.utcnow(),
                limit=limit,
                order_by=order,
                _db_session=db_session)

            # Convert stats list to an image list
            for result in top_stats:
                db_image = data_engine.get_image(image_id=result[0],
                                                 _db_session=db_session)
                if db_image:
                    results.append({
                        'id': db_image.id,
                        'src': db_image.src,
                        'requests': result[1],
                        'views': result[2],
                        'cached_views': result[3],
                        'downloads': result[4],
                        'bytes': result[5],
                        'seconds': result[6],
                        'max_seconds': result[7]
                    })
        finally:
            db_session.close()

        return render_template('reports_topten.html',
                               days=days,
                               data_type=data_type,
                               number=limit,
                               results=results)
    except Exception as e:
        log_security_error(e, request)
        if app.config['DEBUG']:
            raise
        raise InternalServerError(safe_error_str(e))
Exemple #21
0
def trace_permissions():
    embed = request.args.get('embed', '')
    user_id = request.args.get('user', '')
    folder_path = request.args.get('path', '')
    if folder_path == '':
        folder_path = os.path.sep

    folder = None
    user = None
    users = []
    user_has_admin = False
    trace = None
    err_msg = None
    db_session = data_engine.db_get_session()
    try:
        # Get folder and selected user info
        # User can be None for an anonymous user
        user_id = parse_int(user_id)
        if user_id != 0:
            user = data_engine.get_user(user_id, _db_session=db_session)
            if user is None:
                raise DoesNotExistError('This user no longer exists')
        folder = data_engine.get_folder(folder_path=folder_path, _db_session=db_session)
        if folder is None or folder.status == Folder.STATUS_DELETED:
            raise DoesNotExistError('This folder no longer exists')

        # Get users list
        users = data_engine.list_users(
            status=User.STATUS_ACTIVE,
            order_field=User.username,
            _db_session=db_session
        )

        # Get the folder+user traced permissions
        trace = permissions_engine._trace_folder_permissions(folder, user)

        # Flag on the UI if the user has admin
        for gdict in trace['groups']:
            gperms = gdict['group'].permissions
            if gperms.admin_files or gperms.admin_all:
                user_has_admin = True
                break

    except Exception as e:
        log_security_error(e, request)
        err_msg = str(e)
    finally:
        try:
            return render_template(
                'admin_trace_permissions.html',
                embed=embed,
                folder=folder,
                folder_is_root=folder.is_root() if folder else False,
                user=user,
                user_list=users,
                trace=trace,
                user_has_admin=user_has_admin,
                err_msg=err_msg,
                GROUP_ID_PUBLIC=Group.ID_PUBLIC
            )
        finally:
            db_session.close()
Exemple #22
0
def imagelist():
    # Check parameters
    try:
        from_path = request.args.get('path', '')
        want_info = parse_boolean(request.args.get('attributes', ''))
        start = parse_int(request.args.get('start', '0'))
        limit = parse_int(request.args.get('limit', '1000'))
        validate_string(from_path, 1, 1024)
        validate_number(start, 0, 999999999)
        validate_number(limit, 1, 1000)
    except ValueError as e:
        raise ParameterError(e)

    # Get extra parameters for image URL construction, remove API parameters
    image_params = request.args.to_dict()
    image_params.pop('path', None)
    image_params.pop('attributes', None)
    image_params.pop('start', None)
    image_params.pop('limit', None)

    # Get directory listing
    directory_info = get_directory_listing(from_path, False, 2, start, limit)
    if not directory_info.exists():
        raise DoesNotExistError('Invalid path')

    ret_list = []
    db_session = data_engine.db_get_session()
    db_commit = False
    try:
        # Auto-populate the folders database
        db_folder = auto_sync_folder(
            from_path, data_engine, task_engine, _db_session=db_session
        )
        db_session.commit()

        # Require view permission or file admin
        permissions_engine.ensure_folder_permitted(
            db_folder,
            FolderPermission.ACCESS_VIEW,
            get_session_user()
        )
        # Get download permission in case we need to return it later
        can_download = permissions_engine.is_folder_permitted(
            db_folder,
            FolderPermission.ACCESS_DOWNLOAD,
            get_session_user()
        )

        # Create the response
        file_list = directory_info.contents()
        supported_img_types = image_engine.get_image_formats(supported_only=True)
        base_folder = add_sep(directory_info.name())
        for f in file_list:
            # v2.6.4 Return unsupported files too. If you want to reverse this change,
            # the filtering needs to be elsewhere for 'start' and 'limit' to work properly
            supported_file = get_file_extension(f['filename']) in supported_img_types
            file_path = base_folder + f['filename']

            if want_info:
                # Need to return the database fields too
                if supported_file:
                    db_entry = auto_sync_existing_file(
                        file_path,
                        data_engine,
                        task_engine,
                        burst_pdf=False,  # Don't burst a PDF just by finding it here
                        _db_session=db_session
                    )
                    db_entry = _prep_image_object(db_entry, can_download, **image_params)
                else:
                    db_entry = _prep_blank_image_object()
                    db_entry.filename = f['filename']
                    db_entry.supported = False
                # Return images in full (standard) image dict format
                entry = object_to_dict(db_entry, _omit_fields)
            else:
                # Return images in short dict format
                entry = {
                    'filename': f['filename'],
                    'supported': supported_file,
                    'url': (external_url_for('image', src=file_path, **image_params)
                            if supported_file else '')
                }

            ret_list.append(entry)

        db_commit = True
    finally:
        try:
            if db_commit:
                db_session.commit()
            else:
                db_session.rollback()
        finally:
            db_session.close()

    return make_api_success_response(ret_list)
Exemple #23
0
def imagelist():
    # Check parameters
    try:
        from_path = request.args.get('path', '')
        want_info = parse_boolean(request.args.get('attributes', ''))
        limit = parse_int(request.args.get('limit', '1000'))
        validate_string(from_path, 1, 1024)
    except ValueError as e:
        raise ParameterError(e)

    # Get extra parameters for image URL construction
    image_params = request.args.to_dict()
    if 'path' in image_params:
        del image_params['path']
    if 'attributes' in image_params:
        del image_params['attributes']
    if 'limit' in image_params:
        del image_params['limit']

    # Get directory listing
    directory_info = get_directory_listing(from_path, False, limit)
    if not directory_info.exists():
        raise DoesNotExistError('Invalid path')

    ret_list = []
    db_session = data_engine.db_get_session()
    db_commit = False
    try:
        # Auto-populate the folders database
        db_folder = auto_sync_folder(
            from_path, data_engine, task_engine, _db_session=db_session
        )
        db_session.commit()

        # Require view permission or file admin
        permissions_engine.ensure_folder_permitted(
            db_folder,
            FolderPermission.ACCESS_VIEW,
            get_session_user()
        )

        # Create the response
        file_list = directory_info.contents()
        img_types = image_engine.get_image_formats()
        base_folder = add_sep(directory_info.name())
        for f in file_list:
            # Filter out non-images
            if get_file_extension(f['filename']) in img_types:
                entry_path = base_folder + f['filename']
                entry = {
                    'filename': f['filename'],
                    'url': external_url_for('image', src=entry_path, **image_params)
                }
                if want_info:
                    db_entry = auto_sync_existing_file(
                        entry_path,
                        data_engine,
                        task_engine,
                        burst_pdf=False,  # Don't burst a PDF just by finding it here
                        _db_session=db_session
                    )
                    entry['id'] = db_entry.id if db_entry else 0
                    entry['folder_id'] = db_entry.folder_id if db_entry else 0
                    entry['title'] = db_entry.title if db_entry else ''
                    entry['description'] = db_entry.description if db_entry else ''
                    entry['width'] = db_entry.width if db_entry else 0
                    entry['height'] = db_entry.height if db_entry else 0
                ret_list.append(entry)

        db_commit = True
    finally:
        try:
            if db_commit:
                db_session.commit()
            else:
                db_session.rollback()
        finally:
            db_session.close()

    return make_api_success_response(ret_list)
Exemple #24
0
def topten():
    # Get parameters
    days = request.args.get('days', '1')
    limit = request.args.get('number', '10')
    data_type = request.args.get('data_type', '2')
    try:
        results = []
        db_session = data_engine.db_get_session()
        try:
            # Convert params to ints
            days = parse_int(days)
            limit = parse_int(limit)
            data_type = parse_int(data_type)

            # Set options
            if days < 1:
                days = 1
            if days > 30:
                days = 30
            if limit < 10:
                limit = 10
            if limit > 100:
                limit = 100

            if data_type == 1:
                order = '-total_requests'
            elif data_type == 2:
                order = '-total_views'
            elif data_type == 3:
                order = '-total_cached_views'
            elif data_type == 4:
                order = '-total_downloads'
            elif data_type == 5:
                order = '-total_bytes'
            elif data_type == 6:
                order = '-total_seconds'
            elif data_type == 7:
                order = '-max_seconds'
            else:
                raise ValueError('Invalid data_type %d' % data_type)

            # Get initial stats
            top_stats = data_engine.summarise_image_stats(
                datetime.utcnow() - timedelta(days=days),
                datetime.utcnow(),
                limit=limit,
                order_by=order,
                _db_session=db_session
            )

            # Convert stats list to an image list
            for result in top_stats:
                db_image = data_engine.get_image(image_id=result[0], _db_session=db_session)
                if db_image:
                    results.append({
                        'id': db_image.id,
                        'src': db_image.src,
                        'requests': result[1],
                        'views': result[2],
                        'cached_views': result[3],
                        'downloads': result[4],
                        'bytes': result[5],
                        'seconds': result[6],
                        'max_seconds': result[7]
                    })
        finally:
            db_session.close()

        return render_template(
            'reports_topten.html',
            days=days,
            data_type=data_type,
            number=limit,
            results=results
        )
    except Exception as e:
        log_security_error(e, request)
        if app.config['DEBUG']:
            raise
        raise InternalServerError(str(e))