コード例 #1
0
    def before_dataset_search(self, search_params: dict[str, Any]):
        lang_set = set(self.LANGS)

        try:
            current_lang: str = request.environ['CKAN_LANG']
        except TypeError as err:
            if str(err) == ('No object (name: request) has been registered '
                            'for this thread'):
                # This happens when this code gets called as part of a paster
                # command rather then as part of an HTTP request.
                current_lang = config.get_value('ckan.locale_default')
            else:
                raise
        except KeyError:
            current_lang = config.get_value('ckan.locale_default')

        # fallback to default locale if locale not in suported langs
        if not current_lang in lang_set:
            current_lang = config.get_value('ckan.locale_default')
        # fallback to english if default locale is not supported
        if not current_lang in lang_set:
            current_lang = 'en'
        # treat current lang differenly so remove from set
        lang_set.remove(current_lang)

        # weight current lang more highly
        query_fields = 'title_%s^8 text_%s^4' % (current_lang, current_lang)

        for lang in lang_set:
            query_fields += ' title_%s^2 text_%s' % (lang, lang)

        search_params['qf'] = query_fields

        return search_params
コード例 #2
0
    def test_from_field_format(self, mail_server):

        msgs = mail_server.get_smtp_messages()
        assert msgs == []

        # send email
        test_email = {
            "recipient_name": "Bob",
            "recipient_email": "*****@*****.**",
            "subject": "Meeting",
            "body": "The meeting is cancelled.",
            "headers": {
                "header1": "value1"
            },
        }
        mailer.mail_recipient(**test_email)

        # check it went to the mock smtp server
        msgs = mail_server.get_smtp_messages()
        msg = msgs[0]

        expected_from_header = "{0} <{1}>".format(
            config.get_value("ckan.site_title"),
            config.get_value("smtp.mail_from"))

        assert expected_from_header in msg[3]
コード例 #3
0
ファイル: __init__.py プロジェクト: detanxx/ckan
def set_cors_headers_for_response(response: Response) -> Response:
    u'''
    Set up Access Control Allow headers if either origin_allow_all is True, or
    the request Origin is in the origin_whitelist.
    '''
    if request.headers.get(u'Origin'):
        cors_origin_allowed = None
        allow_all = config.get_value(u'ckan.cors.origin_allow_all')
        whitelisted = request.headers.get(u'Origin') in config.get_value(
            u'ckan.cors.origin_whitelist')
        if allow_all:
            cors_origin_allowed = '*'
        elif whitelisted:
            # set var to the origin to allow it.
            cors_origin_allowed: Optional[str] = request.headers.get(u'Origin')

        if cors_origin_allowed is not None:
            response.headers['Access-Control-Allow-Origin'] = \
                cors_origin_allowed
            response.headers['Access-Control-Allow-Methods'] = \
                'POST, PUT, GET, DELETE, OPTIONS'
            response.headers['Access-Control-Allow-Headers'] = \
                'X-CKAN-API-KEY, Authorization, Content-Type'

    return response
コード例 #4
0
ファイル: webassets_tools.py プロジェクト: pdelboca/ckan
def webassets_init():
    global env

    static_path = get_webassets_path()

    public = config.get_value(u'ckan.base_public_folder')

    public_folder = os.path.abspath(
        os.path.join(os.path.dirname(__file__), u'..', public))

    base_path = os.path.join(public_folder, u'base')

    env = Environment()
    env.directory = static_path
    env.debug = config.get_value(u'debug')
    env.url = u'/webassets/'

    add_public_path(base_path, u'/base/')

    logger.debug(u'Base path {0}'.format(base_path))
    create_library(u'vendor', os.path.join(base_path, u'vendor'))

    create_library(u'base', os.path.join(base_path, u'javascript'))

    create_library(u'datapreview', os.path.join(base_path, u'datapreview'))

    create_library(u'css', os.path.join(base_path, u'css'))
コード例 #5
0
ファイル: feed.py プロジェクト: tino097/ckan
def output_feed(results: list[dict[str, Any]], feed_title: str,
                feed_description: str, feed_link: str, feed_url: str,
                navigation_urls: dict[str, str], feed_guid: str) -> Response:
    author_name = config.get_value(u'ckan.feeds.author_name').strip() or \
        config.get_value(u'ckan.site_id').strip()

    def remove_control_characters(s: str):
        if not s:
            return ""

        return "".join(ch for ch in s if unicodedata.category(ch)[0] != "C")

    # TODO: language
    feed_class: PFeedFactory = CKANFeed
    for plugin in plugins.PluginImplementations(plugins.IFeed):
        if hasattr(plugin, u'get_feed_class'):
            feed_class = plugin.get_feed_class()

    feed = feed_class(
        feed_title,
        feed_link,
        feed_description,
        language=u'en',
        author_name=author_name,
        feed_guid=feed_guid,
        feed_url=feed_url,
        previous_page=navigation_urls[u'previous'],
        next_page=navigation_urls[u'next'],
        first_page=navigation_urls[u'first'],
        last_page=navigation_urls[u'last'],
    )

    for pkg in results:
        additional_fields: dict[str, Any] = {}

        for plugin in plugins.PluginImplementations(plugins.IFeed):
            if hasattr(plugin, u'get_item_additional_fields'):
                additional_fields = plugin.get_item_additional_fields(pkg)

        feed.add_item(
            title=pkg.get(u'title', u''),
            link=h.url_for(u'api.action',
                           logic_function=u'package_show',
                           id=pkg['id'],
                           ver=3,
                           _external=True),
            description=remove_control_characters(pkg.get(u'notes', u'')),
            updated=h.date_str_to_datetime(pkg.get(u'metadata_modified', '')),
            published=h.date_str_to_datetime(pkg.get(u'metadata_created', '')),
            unique_id=_create_atom_id(u'/dataset/%s' % pkg['id']),
            author_name=pkg.get(u'author', u''),
            author_email=pkg.get(u'author_email', u''),
            categories=[t[u'name'] for t in pkg.get(u'tags', [])],
            enclosure=_enclosure(pkg),
            **additional_fields)

    resp = make_response(feed.writeString(u'utf-8'), 200)
    resp.headers['Content-Type'] = u'application/atom+xml'
    return resp
コード例 #6
0
def get_reset_link_body(user: model.User) -> str:
    extra_vars = {
        'reset_link': get_reset_link(user),
        'site_title': config.get_value('ckan.site_title'),
        'site_url': config.get_value('ckan.site_url'),
        'user_name': user.name,
    }
    # NOTE: This template is translated
    return render('emails/reset_password.txt', extra_vars)
コード例 #7
0
ファイル: index.py プロジェクト: tino097/ckan
 def delete_package(self, pkg_dict: dict[str, Any]) -> None:
     conn = make_connection()
     query = "+%s:%s AND +(id:\"%s\" OR name:\"%s\") AND +site_id:\"%s\"" % \
             (TYPE_FIELD, PACKAGE_TYPE, pkg_dict.get('id'), pkg_dict.get('id'), config.get_value('ckan.site_id'))
     try:
         commit = config.get_value('ckan.search.solr_commit')
         conn.delete(q=query, commit=commit)
     except Exception as e:
         log.exception(e)
         raise SearchIndexError(e)
コード例 #8
0
def mail_recipient(recipient_name: str,
                   recipient_email: str,
                   subject: str,
                   body: str,
                   body_html: Optional[str] = None,
                   headers: Optional[dict[str, Any]] = None,
                   attachments: Optional[Iterable[Attachment]] = None) -> None:
    '''Sends an email to a an email address.

    .. note:: You need to set up the :ref:`email-settings` to able to send
        emails.

    :param recipient_name: the name of the recipient
    :type recipient: string
    :param recipient_email: the email address of the recipient
    :type recipient: string

    :param subject: the email subject
    :type subject: string
    :param body: the email body, in plain text
    :type body: string
    :param body_html: the email body, in html format (optional)
    :type body_html: string
    :headers: extra headers to add to email, in the form
        {'Header name': 'Header value'}
    :type: dict
    :attachments: a list of tuples containing file attachments to add to the
        email. Tuples should contain the file name and a file-like object
        pointing to the file contents::

            [
                ('some_report.csv', file_object),
            ]

        Optionally, you can add a third element to the tuple containing the
        media type. If not provided, it will be guessed using
        the ``mimetypes`` module::

            [
                ('some_report.csv', file_object, 'text/csv'),
            ]
    :type: list
    '''
    site_title = config.get_value('ckan.site_title')
    site_url = config.get_value('ckan.site_url')
    return _mail_recipient(recipient_name,
                           recipient_email,
                           site_title,
                           site_url,
                           subject,
                           body,
                           body_html=body_html,
                           headers=headers,
                           attachments=attachments)
コード例 #9
0
def _get_locales():
    # FIXME this wants cleaning up and merging with get_locales_from_config()
    assert not config.get('lang'), \
        ('"lang" config option not supported - please use ckan.locale_default '
         'instead.')
    locales_offered = config.get_value('ckan.locales_offered')
    filtered_out = config.get_value('ckan.locales_filtered_out')
    locale_default = config.get_value('ckan.locale_default')
    locale_order = config.get_value('ckan.locale_order')

    locales = ['en']
    i18n_path = get_ckan_i18n_dir()
    # For every file in the ckan i18n directory see if babel can understand
    # the locale. If yes, add it to the available locales
    for locale in os.listdir(i18n_path):
        try:
            Locale.parse(locale)
            locales.append(locale)
        except (ValueError, UnknownLocaleError):
            # Babel does not know how to make a locale out of this.
            # This is fine since we are passing all files in the
            # ckan.i18n_directory here which e.g. includes the __init__.py
            pass

    assert locale_default in locales, \
        'default language "%s" not available' % locale_default

    locale_list = []
    for locale in locales:
        # no duplicates
        if locale in locale_list:
            continue
        # if offered locales then check locale is offered
        if locales_offered and locale not in locales_offered:
            continue
        # remove if filtered out
        if locale in filtered_out:
            continue
        # ignore the default as it will be added first
        if locale == locale_default:
            continue
        locale_list.append(locale)
    # order the list if specified
    ordered_list = [locale_default]
    for locale in locale_order:
        if locale in locale_list:
            ordered_list.append(locale)
            # added so remove from our list
            locale_list.remove(locale)
    # add any remaining locales not ordered
    ordered_list += locale_list

    return ordered_list
コード例 #10
0
    def set_active_backend(cls, config: CKANConfig):
        """Choose most suitable backend depending on configuration

        :param config: configuration object
        :rtype: ckan.common.CKANConfig

        """
        schema = config.get_value(u'ckan.datastore.write_url').split(u':')[0]
        read_schema = config.get_value(
            u'ckan.datastore.read_url').split(u':')[0]
        assert read_schema == schema, u'Read and write engines are different'
        cls._active_backend = cls._backends[schema]()
コード例 #11
0
ファイル: auth_tkt.py プロジェクト: pdelboca/ckan
def make_plugin(secret=None,
                secretfile=None,
                cookie_name='auth_tkt',
                secure=False,
                include_ip=False,
                timeout=None,
                reissue_time=None,
                userid_checker=None):
    from repoze.who.utils import resolveDotted

    # ckan specifics:
    # Get secret from beaker setting if necessary
    if secret is None or secret == u'somesecret':
        secret = config[u'beaker.session.secret']
    # Session timeout and reissue time for auth cookie
    if timeout is None and config.get_value(u'who.timeout'):
        timeout = config[u'who.timeout']
    if reissue_time is None and config.get_value(u'who.reissue_time'):
        reissue_time = config['who.reissue_time']
    if timeout is not None and reissue_time is None:
        reissue_time = int(math.ceil(int(timeout) * 0.1))
    # Set httponly based on config value. Default is True
    httponly = config.get_value(u'who.httponly')
    # Set secure based on config value. Default is False
    secure = config.get_value(u'who.secure')
    # Set samesite based on config value. Default is lax
    samesite = config.get_value(u'who.samesite').lower()
    if samesite == 'none' and not secure:
        raise ValueError('SameSite=None requires the Secure attribute,'
                         'please set who.secure=True')

    # back to repoze boilerplate
    if (secret is None and secretfile is None):
        raise ValueError(u"One of 'secret' or 'secretfile' must not be None.")
    if (secret is not None and secretfile is not None):
        raise ValueError(u"Specify only one of 'secret' or 'secretfile'.")
    if secretfile:
        secretfile = os.path.abspath(os.path.expanduser(secretfile))
        if not os.path.exists(secretfile):
            raise ValueError(u"No such 'secretfile': %s" % secretfile)
        secret = open(secretfile).read().strip()
    if timeout:
        timeout = int(timeout)
    if reissue_time:
        reissue_time = int(reissue_time)
    if userid_checker is not None:
        userid_checker = resolveDotted(userid_checker)
    plugin = CkanAuthTktCookiePlugin(httponly, samesite,
                                     secret, cookie_name, secure,
                                     _bool(include_ip), timeout, reissue_time,
                                     userid_checker)
    return plugin
コード例 #12
0
def get_locales_from_config():
    ''' despite the name of this function it gets the locales defined by
    the config AND also the locals available subject to the config. '''
    locales_offered = config.get_value('ckan.locales_offered')
    filtered_out = config.get_value('ckan.locales_filtered_out')
    locale_default = [config.get_value('ckan.locale_default')]
    locale_order = config.get_value('ckan.locale_order')

    known_locales = get_locales()
    all_locales = (set(known_locales) | set(locales_offered)
                   | set(locale_order) | set(locale_default))
    all_locales -= set(filtered_out)
    return all_locales
コード例 #13
0
ファイル: feed.py プロジェクト: kowh-ai/ckan
def custom():
    """
    Custom atom feed

    """
    q = request.args.get(u'q', u'')
    fq = u''
    search_params = {}
    for (param, value) in request.args.items():
        if param not in [u'q', u'page', u'sort'] \
                and len(value) and not param.startswith(u'_'):
            search_params[param] = value
            fq += u'%s:"%s"' % (param, value)

    page = h.get_page_number(request.args)

    limit = config.get_value('ckan.feeds.limit')
    data_dict = {
        u'q': q,
        u'fq': fq,
        u'start': (page - 1) * limit,
        u'rows': limit,
        u'sort': request.args.get(u'sort', None)
    }

    item_count, results = _package_search(data_dict)

    navigation_urls = _navigation_urls(
        request.args,
        item_count=item_count,
        limit=data_dict['rows'],
        controller=u'feeds',
        action=u'custom')

    feed_url = _feed_url(request.args, controller=u'feeds', action=u'custom')

    atom_url = h._url_with_params(u'/feeds/custom.atom', search_params.items())

    alternate_url = _alternate_url(request.args)
    site_title = config.get_value(u'ckan.site_title')
    return output_feed(
        results,
        feed_title=u'%s - Custom query' % site_title,
        feed_description=u'Recently created or updated'
        ' datasets on %s. Custom query: \'%s\'' % (site_title, q),
        feed_link=alternate_url,
        feed_guid=_create_atom_id(atom_url),
        feed_url=feed_url,
        navigation_urls=navigation_urls)
コード例 #14
0
ファイル: webassets_tools.py プロジェクト: pdelboca/ckan
def get_webassets_path():
    webassets_path = config.get_value(u'ckan.webassets.path')

    if not webassets_path:
        storage_path = config.get_value(
            u'ckan.storage_path') or tempfile.gettempdir()

        if storage_path:
            webassets_path = os.path.join(storage_path, u'webassets')

    if not webassets_path:
        raise RuntimeError(
            u'Either `ckan.webassets.path` or `ckan.storage_path` '
            u'must be specified')
    return webassets_path
コード例 #15
0
ファイル: __init__.py プロジェクト: detanxx/ckan
def handle_i18n(environ: Optional[dict[str, Any]] = None) -> None:
    u'''
    Strips the locale code from the requested url
    (eg '/sk/about' -> '/about') and sets environ variables for the
    language selected:

        * CKAN_LANG is the language code eg en, fr
        * CKAN_LANG_IS_DEFAULT is set to True or False
        * CKAN_CURRENT_URL is set to the current application url
    '''
    environ = environ or request.environ
    assert environ
    locale_list = get_locales_from_config()
    default_locale = config.get_value(u'ckan.locale_default')

    # We only update once for a request so we can keep
    # the language and original url which helps with 404 pages etc
    if u'CKAN_LANG' not in environ:
        path_parts = environ[u'PATH_INFO'].split(u'/')
        if len(path_parts) > 1 and path_parts[1] in locale_list:
            environ[u'CKAN_LANG'] = path_parts[1]
            environ[u'CKAN_LANG_IS_DEFAULT'] = False
            # rewrite url
            if len(path_parts) > 2:
                environ[u'PATH_INFO'] = u'/'.join([u''] + path_parts[2:])
            else:
                environ[u'PATH_INFO'] = u'/'
        else:
            environ[u'CKAN_LANG'] = default_locale
            environ[u'CKAN_LANG_IS_DEFAULT'] = True

        set_ckan_current_url(environ)
コード例 #16
0
def get_ckan_i18n_dir():
    path = config.get_value(u'ckan.i18n_directory') or os.path.join(
        _CKAN_DIR, u'i18n')
    if os.path.isdir(os.path.join(path, u'i18n')):
        path = os.path.join(path, u'i18n')

    return path
コード例 #17
0
ファイル: user.py プロジェクト: tino097/ckan
def index():
    page_number = h.get_page_number(request.args)
    q = request.args.get('q', '')
    order_by = request.args.get('order_by', 'name')
    default_limit: int = config.get_value('ckan.user_list_limit')
    limit = int(request.args.get('limit', default_limit))
    context = cast(
        Context, {
            u'return_query': True,
            u'user': current_user.name,
            u'auth_user_obj': current_user
        })

    data_dict = {u'q': q, u'order_by': order_by}

    try:
        logic.check_access(u'user_list', context, data_dict)
    except logic.NotAuthorized:
        base.abort(403, _(u'Not authorized to see this page'))

    users_list = logic.get_action(u'user_list')(context, data_dict)

    page = h.Page(collection=users_list,
                  page=page_number,
                  url=h.pager_url,
                  item_count=users_list.count(),
                  items_per_page=limit)

    extra_vars: dict[str, Any] = {
        u'page': page,
        u'q': q,
        u'order_by': order_by
    }
    return base.render(u'user/list.html', extra_vars)
コード例 #18
0
ファイル: user.py プロジェクト: pdelboca/ckan
def index():
    page_number = h.get_page_number(request.params)
    q = request.params.get(u'q', u'')
    order_by = request.params.get(u'order_by', u'name')
    limit = int(
        request.params.get(u'limit',
                           config.get_value(u'ckan.user_list_limit')))
    context = {
        u'return_query': True,
        u'user': g.user,
        u'auth_user_obj': g.userobj
    }

    data_dict = {u'q': q, u'order_by': order_by}

    try:
        logic.check_access(u'user_list', context, data_dict)
    except logic.NotAuthorized:
        base.abort(403, _(u'Not authorized to see this page'))

    users_list = logic.get_action(u'user_list')(context, data_dict)

    page = h.Page(collection=users_list,
                  page=page_number,
                  url=h.pager_url,
                  item_count=users_list.count(),
                  items_per_page=limit)

    extra_vars = {u'page': page, u'q': q, u'order_by': order_by}
    return base.render(u'user/list.html', extra_vars)
コード例 #19
0
ファイル: user.py プロジェクト: pdelboca/ckan
    def post(self, id):
        context, user_dict = self._prepare(id)
        context[u'reset_password'] = True
        user_state = user_dict[u'state']
        try:
            new_password = self._get_form_password()
            user_dict[u'password'] = new_password
            username = request.form.get(u'name')
            if (username is not None and username != u''):
                user_dict[u'name'] = username
            user_dict[u'reset_key'] = g.reset_key
            user_dict[u'state'] = model.State.ACTIVE
            logic.get_action(u'user_update')(context, user_dict)
            mailer.create_reset_key(context[u'user_obj'])
            signals.perform_password_reset.send(username,
                                                user=context[u'user_obj'])

            h.flash_success(_(u'Your password has been reset.'))
            return h.redirect_to(
                config.get_value(u'ckan.user_reset_landing_page'))

        except logic.NotAuthorized:
            h.flash_error(_(u'Unauthorized to edit user %s') % id)
        except logic.NotFound:
            h.flash_error(_(u'User not found'))
        except dictization_functions.DataError:
            h.flash_error(_(u'Integrity Error'))
        except logic.ValidationError as e:
            h.flash_error(u'%r' % e.error_dict)
        except ValueError as e:
            h.flash_error(str(e))
        user_dict[u'state'] = user_state
        return base.render(u'user/perform_reset.html',
                           {u'user_dict': user_dict})
コード例 #20
0
ファイル: core.py プロジェクト: tino097/ckan
    def __iter__(self) -> Iterator[TInterface]:
        '''
        When we upgraded pyutilib on CKAN 2.9 the order in which
        plugins were returned by `PluginImplementations` changed
        so we use this wrapper to maintain the previous order
        (which is the same as the ckan.plugins config option)
        '''

        iterator = super(PluginImplementations, self).__iter__()

        plugin_lookup = {pf.name: pf for pf in iterator}

        plugins = config.get_value("ckan.plugins")
        if plugins is None:
            plugins = []
        elif isinstance(plugins, str):
            # this happens when core declarations loaded and validated
            plugins = plugins.split()

        plugins_in_config = plugins + find_system_plugins()

        ordered_plugins = []
        for pc in plugins_in_config:
            if pc in plugin_lookup:
                ordered_plugins.append(plugin_lookup[pc])
                plugin_lookup.pop(pc)

        if plugin_lookup:
            # Any oustanding plugin not in the ini file (ie system ones),
            # add to the end of the iterator
            ordered_plugins.extend(plugin_lookup.values())

        return iter(ordered_plugins)
コード例 #21
0
ファイル: base.py プロジェクト: tino097/ckan
def render_snippet(*template_names: str, **kw: Any) -> str:
    ''' Helper function for rendering snippets. Rendered html has
    comment tags added to show the template used. NOTE: unlike other
    render functions this takes a list of keywords instead of a dict for
    the extra template variables.

    :param template_names: the template to render, optionally with fallback
        values, for when the template can't be found. For each, specify the
        relative path to the template inside the registered tpl_dir.
    :type template_names: str
    :param kw: extra template variables to supply to the template
    :type kw: named arguments of any type that are supported by the template
    '''

    last_exc = None
    for template_name in template_names:
        try:
            output = render(template_name, extra_vars=kw)
            if config.get_value('debug'):
                output = (
                    '\n<!-- Snippet %s start -->\n%s\n<!-- Snippet %s end -->'
                    '\n' % (template_name, output, template_name))
            return h.literal(output)
        except TemplateNotFound as exc:
            if exc.name == template_name:
                # the specified template doesn't exist - try the next
                # fallback, but store the exception in case it was
                # last one
                last_exc = exc
                continue
            # a nested template doesn't exist - don't fallback
            raise exc
    else:
        raise last_exc or TemplatesNotFound(template_names)
コード例 #22
0
ファイル: email_notifications.py プロジェクト: pdelboca/ckan
def get_and_send_notifications_for_user(user):

    # Parse the email_notifications_since config setting, email notifications
    # from longer ago than this time will not be sent.
    email_notifications_since = config.get_value(
        'ckan.email_notifications_since')
    email_notifications_since = string_to_timedelta(email_notifications_since)
    email_notifications_since = (datetime.datetime.utcnow() -
                                 email_notifications_since)

    # FIXME: We are accessing model from lib here but I'm not sure what
    # else to do unless we add a get_email_last_sent() logic function which
    # would only be needed by this lib.
    email_last_sent = model.Dashboard.get(user['id']).email_last_sent
    activity_stream_last_viewed = (model.Dashboard.get(
        user['id']).activity_stream_last_viewed)

    since = max(email_notifications_since, email_last_sent,
                activity_stream_last_viewed)

    notifications = get_notifications(user, since)
    # TODO: Handle failures from send_email_notification.
    for notification in notifications:
        send_notification(user, notification)

    # FIXME: We are accessing model from lib here but I'm not sure what
    # else to do unless we add a update_email_last_sent()
    # logic function which would only be needed by this lib.
    dash = model.Dashboard.get(user['id'])
    dash.email_last_sent = datetime.datetime.utcnow()
    model.repo.commit()
コード例 #23
0
ファイル: flask_app.py プロジェクト: frafra/ckan
def _register_error_handler(app: CKANApp):
    u'''Register error handler'''
    def error_handler(e: Exception) -> tuple[str, Optional[int]]:
        debug = config.get_value('debug')
        if isinstance(e, HTTPException):
            if debug:
                log.debug(e, exc_info=sys.exc_info)  # type: ignore
            else:
                log.info(e)
            extra_vars = {
                u'code': e.code,
                u'content': e.description,
                u'name': e.name
            }

            return base.render(u'error_document_template.html',
                               extra_vars), e.code

        log.error(e, exc_info=sys.exc_info)  # type: ignore
        extra_vars = {u'code': [500], u'content': u'Internal server error'}
        return base.render(u'error_document_template.html', extra_vars), 500

    for code in default_exceptions:
        app.register_error_handler(code, error_handler)
    if not app.debug and not app.testing:
        app.register_error_handler(Exception, error_handler)
        if config.get_value('email_to'):
            _setup_error_mail_handler(app)
コード例 #24
0
    def test_can_view(self):
        url_same_domain = urljoin(config.get_value('ckan.site_url'),
                                  '/resource.txt')
        url_different_domain = 'http://some.com/resource.txt'

        data_dict = {
            'resource': {
                'format': 'jsonp',
                'url': url_different_domain
            }
        }
        assert self.p.can_view(data_dict)

        data_dict = {'resource': {'format': 'json', 'url': url_same_domain}}
        assert self.p.can_view(data_dict)

        data_dict = {'resource': {'format': 'xml', 'url': url_same_domain}}
        assert self.p.can_view(data_dict)

        data_dict = {'resource': {'format': 'txt', 'url': url_same_domain}}
        assert self.p.can_view(data_dict)

        data_dict = {'resource': {'format': 'foo', 'url': url_same_domain}}
        assert not self.p.can_view(data_dict)

        data_dict = {
            'resource': {
                'format': 'json',
                'url': url_different_domain
            }
        }

        assert not self.p.can_view(data_dict)
コード例 #25
0
def user_show(context: Context, data_dict: DataDict) -> AuthResult:
    # By default, user details can be read by anyone, but some properties like
    # the API key are stripped at the action level if not not logged in.
    if not config.get_value('ckan.auth.public_user_details'):
        return restrict_anon(context)
    else:
        return {'success': True}
コード例 #26
0
def check_recaptcha(request):
    '''Check a user\'s recaptcha submission is valid, and raise CaptchaError
    on failure.'''
    recaptcha_private_key = config.get_value('ckan.recaptcha.privatekey')
    if not recaptcha_private_key:
        # Recaptcha not enabled
        return

    client_ip_address = request.environ.get('REMOTE_ADDR',
                                            'Unknown IP Address')

    # reCAPTCHA v2
    recaptcha_response_field = request.form.get('g-recaptcha-response', '')
    recaptcha_server_name = 'https://www.google.com/recaptcha/api/siteverify'

    # recaptcha_response_field will be unicode if there are foreign chars in
    # the user input. So we need to encode it as utf8 before urlencoding or
    # we get an exception (#1431).
    params = dict(secret=recaptcha_private_key,
                  remoteip=client_ip_address,
                  response=recaptcha_response_field.encode('utf8'))
    response = requests.get(recaptcha_server_name, params)
    data = response.json()

    try:
        if not data['success']:
            raise CaptchaError()
    except IndexError:
        # Something weird with recaptcha response
        raise CaptchaError()
コード例 #27
0
ファイル: feed.py プロジェクト: tino097/ckan
def tag(id: str) -> Response:
    data_dict, params = _parse_url_params()
    data_dict['fq'] = u'tags: "%s"' % id

    item_count, results = _package_search(data_dict)

    navigation_urls = _navigation_urls(params,
                                       item_count=item_count,
                                       limit=data_dict['rows'],
                                       controller=u'feeds',
                                       action=u'tag',
                                       id=id)

    feed_url = _feed_url(params, controller=u'feeds', action=u'tag', id=id)

    alternate_url = _alternate_url(params, tags=id)

    site_title = config.get_value(u'ckan.site_title')
    title = u'%s - Tag: "%s"' % (site_title, id)
    desc = u'Recently created or updated datasets on %s by tag: "%s"' % \
           (site_title, id)
    guid = _create_atom_id(u'/feeds/tag/%s.atom' % id)

    return output_feed(results,
                       feed_title=title,
                       feed_description=desc,
                       feed_link=alternate_url,
                       feed_guid=guid,
                       feed_url=feed_url,
                       navigation_urls=navigation_urls)
コード例 #28
0
ファイル: package.py プロジェクト: frafra/ckan
 def as_dict(self,
             ref_package_by: str = 'name',
             ref_group_by: str = 'name') -> dict[str, Any]:
     _dict = domain_object.DomainObject.as_dict(self)
     # Set 'license' in _dict to cater for old clients.
     # Todo: Remove from Version 2?
     _dict['license'] = self.license.title if self.license else _dict.get(
         'license_id', '')
     _dict['isopen'] = self.isopen()
     tags = [tag.name for tag in self.get_tags()]
     tags.sort()  # so it is determinable
     _dict['tags'] = tags
     groups = [getattr(group, ref_group_by) for group in self.get_groups()]
     groups.sort()
     _dict['groups'] = groups
     _dict['extras'] = {key: value for key, value in self.extras.items()}
     _dict['resources'] = [res.as_dict(core_columns_only=False) \
                           for res in self.resources]
     site_url = config.get_value('ckan.site_url')
     if site_url:
         _dict['ckan_url'] = '%s/dataset/%s' % (site_url, self.name)
     _dict['relationships'] = [
         rel.as_dict(self, ref_package_by=ref_package_by)
         for rel in self.get_relationships()
     ]
     _dict['metadata_modified'] = self.metadata_modified.isoformat() \
         if self.metadata_modified else None
     _dict['metadata_created'] = self.metadata_created.isoformat() \
         if self.metadata_created else None
     import ckan.lib.helpers as h
     _dict['notes_rendered'] = h.render_markdown(self.notes)
     _dict['type'] = self.type or u'dataset'
     return _dict
コード例 #29
0
ファイル: feed.py プロジェクト: tino097/ckan
def general() -> Response:
    data_dict, params = _parse_url_params()
    data_dict['q'] = u'*:*'

    item_count, results = _package_search(data_dict)

    navigation_urls = _navigation_urls(params,
                                       item_count=item_count,
                                       limit=data_dict['rows'],
                                       controller=u'feeds',
                                       action=u'general')

    feed_url = _feed_url(params, controller=u'feeds', action=u'general')

    alternate_url = _alternate_url(params)

    guid = _create_atom_id(u'/feeds/dataset.atom')

    site_title = config.get_value(u'ckan.site_title')
    desc = u'Recently created or updated datasets on %s' % site_title

    return output_feed(results,
                       feed_title=site_title,
                       feed_description=desc,
                       feed_link=alternate_url,
                       feed_guid=guid,
                       feed_url=feed_url,
                       navigation_urls=navigation_urls)
コード例 #30
0
ファイル: base.py プロジェクト: tino097/ckan
def _allow_caching(cache_force: Optional[bool] = None):
    # Caching Logic

    allow_cache = True
    # Force cache or not if explicit.
    if cache_force is not None:
        allow_cache = cache_force
    # Do not allow caching of pages for logged in users/flash messages etc.
    elif ('user' in g and g.user) or _is_valid_session_cookie_data():
        allow_cache = False
    # Tests etc.
    elif session.get("_user_id"):
        allow_cache = False
    # Don't cache if based on a non-cachable template used in this.
    elif request.environ.get('__no_cache__'):
        allow_cache = False
    # Don't cache if we have set the __no_cache__ param in the query string.
    elif request.args.get('__no_cache__'):
        allow_cache = False
    # Don't cache if caching is not enabled in config
    elif not config.get_value('ckan.cache_enabled'):
        allow_cache = False

    if not allow_cache:
        # Prevent any further rendering from being cached.
        request.environ['__no_cache__'] = True