Пример #1
0
def issues_enabled(dataset):
    '''Returns whether issues are enabled for the given dataset (dict)'''
    # config options allow you to only enable issues for particular datasets or
    # organizations
    datasets_with_issues_enabled = set(
        toolkit.aslist(config.get('ckanext.issues.enabled_for_datasets')))
    organizations_with_issues_enabled = set(
        toolkit.aslist(config.get('ckanext.issues.enabled_for_organizations')))
    if datasets_with_issues_enabled or organizations_with_issues_enabled:
        if datasets_with_issues_enabled and \
                dataset['name'] in datasets_with_issues_enabled:
            return True
        elif organizations_with_issues_enabled and \
                (dataset.get('organization') or {}).get('name') in \
                organizations_with_issues_enabled:
            return True
        return False
    else:
        extras = dataset.get('extras', [])
        for extra in extras:
            if extra.get('key') == 'issues_enabled':
                return toolkit.asbool(extra.get('value'))
        else:
            return toolkit.asbool(
                config.get('ckanext.issues.enabled_without_extra', True))
Пример #2
0
def is_resource_blacklisted(resource):
    package = toolkit.get_action('package_show')({'ignore_auth': True}, {
        'id': resource['package_id'],
    })

    org_blacklist = list(set(toolkit.aslist(config.get('ckan.spatialingestor.org_blacklist', []))))
    pkg_blacklist = list(set(toolkit.aslist(config.get('ckan.spatialingestor.pkg_blacklist', []))))
    user_blacklist = list(
        set(map(lambda x: model.User.get(x).id, toolkit.aslist(config.get('ckan.spatialingestor.user_blacklist', [])))))

    if package['organization']['name'] in org_blacklist:
        log.error("{0} in organization blacklist".format(package['organization']['name']))
        return True
    elif package['name'] in pkg_blacklist:
        log.error("{0} in package blacklist".format(package['name']))
        return True
    else:
        activity_list = toolkit.get_action('package_activity_list')({'ignore_auth': True}, {
            'id': package['id'],
        })

        last_user = package['creator_user_id']
        if activity_list:
            last_user = activity_list[0]['user_id']

        if last_user in user_blacklist:
            log.error("{0} was last edited by blacklisted user".format(activity_list[0]['user_id']))
            return True

    return False
Пример #3
0
    def before_create(self, context, resource):
        disallowed_extensions = toolkit.aslist(config.get('ckanext.romania_theme.disallowed_extensions',[]))
        disallowed_mimetypes = [mimetypes.types_map["." + x] for x in disallowed_extensions]

        allowed_extensions = toolkit.aslist(config.get('ckanext.romania_theme.allowed_extensions',[]))
        allowed_mimetypes = [mimetypes.types_map["." + x] for x in allowed_extensions]

        is_resource_extension_allowed = False
        error_message = ''
        if allowed_mimetypes:
            if resource['upload'].type in allowed_mimetypes:
                is_resource_extension_allowed = True
            else:
                error_message="Doar urmatoarele extensii sunt permise: " + ", ".join(allowed_extensions) + "."
        else:
            if resource['upload'].type not in disallowed_mimetypes:
                is_resource_extension_allowed = True
            else:
                error_message= "Urmatoarele extensii sunt nepermise: " + ", ".join(disallowed_extensions) + "."

        if ('upload' in resource) and (type(resource['upload']) is not unicode) and not is_resource_extension_allowed:
            # If we did not do this, the URL field would contain the filename
            # and people can press finalize afterwards.
            resource['url'] = ''


            raise toolkit.ValidationError(['Fisierul are o extensie nepermisa! ' + error_message])
Пример #4
0
    def before_create(self, context, resource):
        disallowed_extensions = toolkit.aslist(config.get('ckanext.datagovro_theme.disallowed_extensions',[]))
        disallowed_mimetypes = [mimetypes.types_map["." + x] for x in disallowed_extensions]

        allowed_extensions = toolkit.aslist(config.get('ckanext.datagovro_theme.allowed_extensions',[]))
        allowed_mimetypes = [mimetypes.types_map["." + x] for x in allowed_extensions]

        is_resource_extension_allowed = False
        error_message = ''
        if (type(resource['upload']) is not unicode):
            if allowed_mimetypes:
                if resource['upload'].type in allowed_mimetypes:
                    is_resource_extension_allowed = True
                else:
                    error_message="Doar urmatoarele extensii sunt permise: " + ", ".join(allowed_extensions) + "."
            else:
                if resource['upload'].type not in disallowed_mimetypes:
                    is_resource_extension_allowed = True
                else:
                    error_message= "Urmatoarele extensii sunt nepermise: " + ", ".join(disallowed_extensions) + "."

        # is_resource_extension_allowed = True
        if ('upload' in resource) and (type(resource['upload']) is not unicode) and not is_resource_extension_allowed:
            # If we did not do this, the URL field would contain the filename
            # and people can press finalize afterwards.
            resource['url'] = ''

            raise toolkit.ValidationError(['Fisierul are o extensie nepermisa! ' + error_message])
            is_resource_extension_allowed = False
Пример #5
0
def issues_enabled(dataset):
    '''Returns whether issues are enabled for the given dataset (dict)'''
    # config options allow you to only enable issues for particular datasets or
    # organizations
    datasets_with_issues_enabled = set(toolkit.aslist(
        config.get('ckanext.issues.enabled_for_datasets')
    ))
    organizations_with_issues_enabled = set(toolkit.aslist(
        config.get('ckanext.issues.enabled_for_organizations')
    ))
    if datasets_with_issues_enabled or organizations_with_issues_enabled:
        if datasets_with_issues_enabled and \
                dataset['name'] in datasets_with_issues_enabled:
            return True
        elif organizations_with_issues_enabled and \
                (dataset.get('organization') or {}).get('name') in \
                organizations_with_issues_enabled:
            return True
        return False
    else:
        extras = dataset.get('extras', [])
        for extra in extras:
            if extra.get('key') == 'issues_enabled':
                return toolkit.asbool(extra.get('value'))
        else:
            return toolkit.asbool(
                config.get('ckanext.issues.enabled_without_extra', True)
            )
Пример #6
0
    def update_config(self, config):
        u'''
        Load config and set up the resource library,
        public directory and template directory for the view
        '''

        # https://datatables.net/reference/option/lengthMenu
        self.page_length_choices = toolkit.aslist(
            config.get(u'ckan.datatables.page_length_choices',
                       DEFAULT_PAGE_LENGTH_CHOICES))
        self.page_length_choices = [int(i) for i in self.page_length_choices]
        self.top_pagination_controls = toolkit.asbool(
            config.get(u'ckan.datatables.top_pagination_controls', False))
        self.search_delay = toolkit.asint(
            config.get(u'ckan.datatables.search_delay', DEFAULT_SEARCH_DELAY))
        self.state_saving = toolkit.asbool(
            config.get(u'ckan.datatables.state_saving', True))
        # https://datatables.net/reference/option/stateDuration
        self.state_duration = toolkit.asint(
            config.get(u'ckan.datatables.state_duration',
                       DEFAULT_STATE_DURATION))
        self.data_dictionary_labels = toolkit.asbool(
            config.get(u'ckan.datatables.data_dictionary_labels', True))

        toolkit.add_template_directory(config, u'templates')
        toolkit.add_public_directory(config, u'public')
        toolkit.add_resource(u'public', u'ckanext-datatablesview')
Пример #7
0
    def get_resource_info_by_id(cls, resource_id):
        resource = model.Session.query(
            model.Resource).filter(model.Resource.id == resource_id).first()
        res_name = None
        res_package_name = None
        res_package_id = None

        if resource is not None:
            res_package_name = resource.package.title or resource.package.name
            res_package_id = resource.package.name

            name_translated_json = resource.extras.get('name_translated')
            if name_translated_json is not None:
                try:
                    name_translated = json.loads(name_translated_json)
                    languages = aslist(config.get('ckan.locales_offered', []))
                    res_name = next(
                        (name_translated[lang]
                         for lang in languages if name_translated.get(lang)),
                        None)
                except json.JSONDecodeError:
                    pass

            res_name = res_name or resource.description or resource.format

        return [res_name, res_package_name, res_package_id]
Пример #8
0
    def update_config(self, config):
        u'''
        Set up the resource library, public directory and
        template directory for the view
        '''

        # https://datatables.net/reference/option/lengthMenu
        self.page_length_choices = toolkit.aslist(
            config.get(u'ckan.datatables.page_length_choices',
                       DEFAULT_PAGE_LENGTH_CHOICES))
        self.page_length_choices = [int(i) for i in self.page_length_choices]
        self.state_saving = toolkit.asbool(
            config.get(u'ckan.datatables.state_saving', True))
        # https://datatables.net/reference/option/stateDuration
        self.state_duration = toolkit.asint(
            config.get(u'ckan.datatables.state_duration',
                       DEFAULT_STATE_DURATION))
        self.data_dictionary_labels = toolkit.asbool(
            config.get(u'ckan.datatables.data_dictionary_labels', True))
        self.ellipsis_length = toolkit.asint(
            config.get(u'ckan.datatables.ellipsis_length',
                       DEFAULT_ELLIPSIS_LENGTH))
        self.date_format = config.get(u'ckan.datatables.date_format',
                                      DEFAULT_DATE_FORMAT)
        self.default_view = config.get(u'ckan.datatables.default_view',
                                       'table')
        toolkit.add_template_directory(config, u'templates')
        toolkit.add_public_directory(config, u'public')
        toolkit.add_resource(u'public', u'ckanext-datatablesview')
Пример #9
0
def run(ctx, host, port, disable_reloader, threaded, extra_files, processes):
    u"""Runs the Werkzeug development server"""
    use_reloader = not disable_reloader
    threaded = threaded or tk.asbool(config.get(u"ckan.devserver.threaded"))
    processes = processes or tk.asint(
        config.get(u"ckan.devserver.multiprocess", 1)
    )
    if threaded and processes > 1:
        tk.error_shout(u"Cannot have a multithreaded and multi process server")
        raise click.Abort()

    log.info(u"Running server {0} on port {1}".format(host, port))

    config_extra_files = tk.aslist(
        config.get(u"ckan.devserver.watch_patterns")
    )
    extra_files = list(extra_files) + [
        config[u"__file__"]
    ] + config_extra_files

    run_simple(
        host,
        port,
        ctx.obj.app,
        use_reloader=use_reloader,
        use_evalex=True,
        threaded=threaded,
        processes=processes,
        extra_files=extra_files,
    )
Пример #10
0
    def update_config_schema(self, schema):
        ignore_missing = toolkit.get_validator('ignore_missing')

        charts = {}
        for _ in range(1, 5):
            charts.update({
                'ckanext.eds.chart_{idx}'.format(idx=_):
                [ignore_missing, unicode],
                'ckanext.eds.chart_{idx}_subheader'.format(idx=_):
                [ignore_missing, unicode]
            })

        for l in get_available_locales():
            if l.short_name in toolkit.aslist(
                    config.get('ckanext.eds.available_locales', 'en da_DK')):
                schema.update({
                    'ckan.site_intro_text_{0}'.format(l):
                    [ignore_missing, unicode],
                    'ckan.site_description_{0}'.format(l):
                    [ignore_missing, unicode],
                    'ckan.site_about_{0}'.format(l): [ignore_missing, unicode],
                    'ckan.site_title_{0}'.format(l): [ignore_missing, unicode],
                    'ckan.cookie_notice_content_{0}'.format(l):
                    [ignore_missing, unicode],
                    'api_guides_content_{0}'.format(l):
                    [ignore_missing, unicode],
                    'simple_guides_content_{0}'.format(l):
                    [ignore_missing, unicode]
                })

        schema.update(charts)

        return schema
Пример #11
0
def syndicate_configs_from_config(config) -> Iterable[Profile]:
    prefix = "ckan.syndicate."
    keys = (
        "api_key",
        "author",
        "extras",
        "field_id",
        "flag",
        "organization",
        "predicate",
        "name_prefix",
        "replicate_organization",
        "ckan_url",
    )

    profile_lists = zip_longest(
        *[tk.aslist(config.get(prefix + key)) for key in keys])

    for idx, item in enumerate(profile_lists):
        deprecated(f"Deprecated profile definition: {item}. Use"
                   f" {PROFILE_PREFIX}*.OPTION form")
        data = dict((k, v) for k, v in zip(keys, item) if v is not None)

        try:
            data["extras"] = json.loads(data.get("extras", "{}"))
        except (TypeError, ValueError):
            data["extras"] = {}
        yield Profile(id=str(idx), **data)

    yield from _parse_profiles(config)
Пример #12
0
def mimetype_autocomplete(context, data_dict):
    '''Return a list of MIME types whose names contain a string.

    :param q: the string to search for
    :type q: string
    :param limit: the maximum number of resource formats to return (optional,default: 5)
    :type limit: int

    :rtype: list of strings
    '''

    _check_access('site_read', context, data_dict)

    q = data_dict.get('q', None)
    if not q:
        return []

    limit = int(data_dict.get('limit', 5))

    mime_types = toolkit.aslist(
        config.get('ckanext.publicamundi.mime_types', ''))
    results = []
    n = 0
    for t in mime_types:
        if t.find(q) >= 0:
            results.append(t)
            n += 1
            if n == limit:
                break

    return results
Пример #13
0
def run(ctx, host, port, disable_reloader, threaded, extra_files, processes,
        ssl_cert, ssl_key):
    u"""Runs the Werkzeug development server"""

    if tk.asbool(config.get("debug")):
        warnings.filterwarnings("default", category=CkanDeprecationWarning)

    # Reloading
    use_reloader = not disable_reloader
    config_extra_files = tk.aslist(
        config.get(u"ckan.devserver.watch_patterns")
    )
    extra_files = list(extra_files) + [
        config[u"__file__"]
    ] + config_extra_files

    # Threads and processes
    threaded = threaded or tk.asbool(config.get(u"ckan.devserver.threaded"))
    processes = processes or tk.asint(
        config.get(u"ckan.devserver.multiprocess", 1)
    )
    if threaded and processes > 1:
        tk.error_shout(u"Cannot have a multithreaded and multi process server")
        raise click.Abort()

    # SSL
    cert_file = ssl_cert or config.get('ckan.devserver.ssl_cert')
    key_file = ssl_key or config.get('ckan.devserver.ssl_key')

    if cert_file and key_file:
        if cert_file == key_file == 'adhoc':
            ssl_context = 'adhoc'
        else:
            ssl_context = (ssl_cert, ssl_key)
    else:
        ssl_context = None

    host = host or config.get('ckan.devserver.host', DEFAULT_HOST)
    port = port or config.get('ckan.devserver.port', DEFAULT_PORT)
    try:
        port = int(port)
    except ValueError:
        tk.error_shout(u"Server port must be an integer, not {}".format(port))
        raise click.Abort()

    log.info(u"Running CKAN on {scheme}://{host}:{port}".format(
        scheme='https' if ssl_context else 'http', host=host, port=port))

    run_simple(
        host,
        port,
        ctx.obj.app,
        use_reloader=use_reloader,
        use_evalex=True,
        threaded=threaded,
        processes=processes,
        extra_files=extra_files,
        ssl_context=ssl_context,
    )
Пример #14
0
def issues_enabled_for_organization(organization):
    '''Returns whether issues are enabled for the given organization (dict)'''
    organizations_with_issues_enabled = set(
        toolkit.aslist(config.get('ckanext.issues.enabled_for_organizations')))
    if organizations_with_issues_enabled:
        return organization and \
            organization.get('name') in organizations_with_issues_enabled
    return True
Пример #15
0
def issues_enabled_for_organization(organization):
    '''Returns whether issues are enabled for the given organization (dict)'''
    organizations_with_issues_enabled = set(toolkit.aslist(
        config.get('ckanext.issues.enabled_for_organizations')
    ))
    if organizations_with_issues_enabled:
        return organization and \
            organization.get('name') in organizations_with_issues_enabled
    return True
Пример #16
0
def hierarchy_enable_tree_search():
    if not tk.request:
        return False
    endpoint = ".".join(tk.get_endpoint())
    supported_endpoints = tk.aslist(
        tk.config.get(
            CONFIG_TREE_SEARCH_EDNPOINTS, DEFAULT_TREE_SEARCH_ENDPOINTS
        )
    )
    return endpoint in supported_endpoints
Пример #17
0
def select_indexable_resources(resources):
    """
    Filter out resources with unsupported formats
    Returns a list of resources dicts
    """
    supported = tk.aslist(
        tk.config.get("ckanext.resource_indexer.indexable_formats"))
    return [
        res for res in resources if res.get("format", "").lower() in supported
    ]
Пример #18
0
    def setup_template_variables(self, context, data_dict):
        layers = toolkit.aslist(config.get('ckanext.mvt.mapbox.style', ''))
        labels = toolkit.aslist(config.get('ckanext.mvt.mapbox.style_label', ''))
        cache = lib.CacheHandler(MvtPlugin.TEMPDIR)
        if len(labels) != len(layers):
            log.warn('The config file contains {0} layer id\'s and {1} labels. The extension needs an equal amount and can only use the first {2}'.format(len(labels), len(layers), min(len(layers),len(labels))))

        baseLayers = [];
        for i in range(min(len(layers),len(labels))):
            baseLayers.append({"id": layers[i], "label": labels[i]})

        return {
            'tilejson': data_dict['resource'].get('tilejson', ''),
            'mapbox': {
                'account': config.get('ckanext.mvt.mapbox.account', ''),
                'key': config.get('ckanext.mvt.mapbox.key', ''),
                'defaultStyle': toolkit.aslist(config.get('ckanext.mvt.mapbox.style', ''))[0],
                'styles': baseLayers
            },
            'resource_job_status': cache.get_job_status(data_dict['resource'].get('id'))
        }
Пример #19
0
    def configure(self, config_):
        # Setup database tables
        db_setup()

        # Load and parse user attributes mapping
        user_mapping = t.aslist(config_.get('ckanext.cas.user_mapping'))
        for attr in user_mapping:
            key, val = attr.split('~')
            if '+' in val:
                val = val.split('+')
            self.USER_ATTR_MAP.update({key: val})

        if not any(self.USER_ATTR_MAP):
            raise RuntimeError, 'User attribute mapping is required for plugin: {0}'.format(self.name)

        if 'email' not in self.USER_ATTR_MAP.keys():
            raise RuntimeError, '"email" attribute mapping is required for plugin: {0}'.format(self.name)

        service_validation_url = config.get('ckanext.cas.service_validation_url', None)
        saml_validation_url = config.get('ckanext.cas.saml_validation_url', None)

        if (service_validation_url and saml_validation_url) or \
                (not service_validation_url and not saml_validation_url):
            msg = 'Configure either "ckanext.cas.service_validation_url" or "ckanext.cas.saml_validation_url" but not both.'
            raise RuntimeError, msg

        if not config.get('ckanext.cas.login_url', None):
            raise RuntimeError, '"ckanext.cas.login_url" is required for plugin: {0}'.format(self.name)

        if not config.get('ckanext.cas.logout_url', None):
            raise RuntimeError, '"ckanext.cas.logout_url" is required for plugin: {0}'.format(self.name)

        if not config.get('ckanext.cas.application_url', None):
            raise RuntimeError, '"ckanext.cas.application_url" is required for plugin: {0}'.format(self.name)

        if service_validation_url:
            self.SERVICE_VALIDATION_URL = config.get('ckanext.cas.service_validation_url')
            self.CAS_VERSION = 2
        elif saml_validation_url:
            self.SAML_VALIDATION_URL = config.get('ckanext.cas.saml_validation_url')
            self.CAS_VERSION = 3

        self.CAS_LOGIN_URL = config.get('ckanext.cas.login_url')
        self.CAS_LOGOUT_URL = config.get('ckanext.cas.logout_url')
        self.CAS_APP_URL = config.get('ckanext.cas.application_url')
        self.CAS_COOKIE_NAME = config.get('ckanext.cas.cookie_name', 'sessionid')
        self.TICKET_KEY = config.get('ckanext.cas.ticket_key', 'ticket')
        self.SERVICE_KEY = config.get('ckanext.cas.service_key', 'service')
        self.REDIRECT_ON_UNSUCCESSFUL_LOGIN = config.get('ckanext.cas.unsuccessful_login_redirect_url', None)
        self.LOGIN_CHECKUP_TIME = t.asint(config.get('ckanext.cas.login_checkup_time', 600))
        self.LOGIN_CHECKUP_COOKIE = config.get('ckanext.cas.login_checkup_cookie', 'cas_login_check')
        self.VERIFY_CERTIFICATE = t.asbool(config.get('ckanext.cas.verify_certificate', True))
Пример #20
0
 def get_helpers(self):
     return {
         'str_to_dict':
         str_to_dict,
         'resource_excluded_fields':
         lambda: toolkit.aslist(
             config.get('ckanext.edsmetadata.resource_excluded_fields',
                        'attributes filters format ')),
         'split_string':
         lambda text, delim: text.split(delim),
         'markdown_fields':
         _h.markdown_fields
     }
Пример #21
0
def get_microservice_metadata():
    for config_option in ('ckan.spatialingestor.postgis_url', 'ckan.spatialingestor.internal_geoserver_url',):
        if not config.get(config_option):
            raise Exception(
                'Config option `{0}` must be set to use the SpatialIngestor.'.format(config_option))

    core_url = config.get('ckan.site_url', 'http://localhost:8000/')
    return {'postgis': cli.parse_db_config('ckan.spatialingestor.postgis_url'),
            'geoserver': cli.parse_db_config('ckan.spatialingestor.internal_geoserver_url'),
            'geoserver_public_url': config.get('ckan.spatialingestor.public_geoserver_url',
                                               core_url + '/geoserver'),
            'target_spatial_formats': list(set([x.upper() for x in toolkit.aslist(config.get('ckan.spatialingestor.target_formats', []))]))
            }
    def configure(self, config_):
        results.create_database_table()

        # Update the class variables for the config settings with the values
        # from the config file, *if* they're in the config file.
        config.recheck_resources_after = toolkit.asint(
            config_.get("ckanext.deadoralive.recheck_resources_after",
                        config.recheck_resources_after))
        config.resend_pending_resources_after = toolkit.asint(
            config_.get("ckanext.deadoralive.resend_pending_resources_after",
                        config.resend_pending_resources_after))
        config.broken_resource_min_fails = toolkit.asint(
            config_.get("ckanext.deadoralive.broken_resource_min_fails",
                        config.broken_resource_min_fails))
        config.broken_resource_min_hours = toolkit.asint(
            config_.get("ckanext.deadoralive.broken_resource_min_hours",
                        config.broken_resource_min_hours))
        config.authorized_users = toolkit.aslist(
            config_.get("ckanext.deadoralive.authorized_users",
                        config.authorized_users))
        config.organization_to_filter = toolkit.aslist(
            config_.get("ckanext.deadoralive.organization_to_filter",
                        config.organization_to_filter))
Пример #23
0
    def configure(self, config):
        formats = toolkit.aslist(
            config.get('ckanext.datastorer.formats', interesting_formats))
        self.interesting_formats = set(interesting_formats) & set(formats) 
        
        logger.info('Interested in resource formats: %s' %(
            ', '.join(self.interesting_formats)))

        try:
            sample_size = int(config.get('ckanext.datastorer.sample_size'))
        except:
            self.sample_size = None
        else:
            self.sample_size = sample_size 
Пример #24
0
    def dataset_facets(self, facets_dict, package_type):
        # 'Stikkord' and 'Formater' in Norwegian.
        default_included_facets = ['tags', 'res_format']
        # Gets the facets from config properties, if property is defined. Otherwise sets to default values.
        included_facets = toolkit.aslist(
            config.get('tolltheme.dataset.filters', default_included_facets))
        if '*' in included_facets:
            return facets_dict

        facets = OrderedDict()
        for key, value in facets_dict.items():
            if key in included_facets or value in included_facets:
                facets[key] = value
        return facets
Пример #25
0
    def configure(self, config):
        formats = toolkit.aslist(
            config.get('ckanext.datastorer.formats', interesting_formats))
        self.interesting_formats = set(interesting_formats) & set(formats)

        logger.info('Interested in resource formats: %s' %
                    (', '.join(self.interesting_formats)))

        try:
            sample_size = int(config.get('ckanext.datastorer.sample_size'))
        except:
            self.sample_size = None
        else:
            self.sample_size = sample_size
Пример #26
0
def issues_enabled(dataset):
    datasets_with_issues_enabled = set(
        toolkit.aslist(config.get('ckanext.issues.enabled_for_datasets')))
    # if the config option 'ckanext.issues.enabled_for_dataset' is
    # set with a list of datasets, only enabled for the listed datasets
    if datasets_with_issues_enabled:
        if dataset['name'] in datasets_with_issues_enabled:
            return True
    else:
        extras = dataset.get('extras')
        if extras is not None:
            for extra in extras:
                if extra.get('key') == 'issues_enabled':
                    return toolkit.asbool(extra.get('value'))
        else:
            return toolkit.asbool(
                config.get('ckanext.issues.enabled_per_dataset_default', True))
Пример #27
0
    def __call__(self, environ, start_response):
        # if logged in via browser cookies all pages accessible
        if 'repoze.who.identity' not in environ:
            # If api request check for api key
            if environ['PATH_INFO'].startswith('/api/action/') \
                    or environ['PATH_INFO'].startswith('/api/util/') \
                    or environ['PATH_INFO'].startswith('/api/i18n/'):
                # All API requests require authenticated api keys
                if not self._get_user_for_apikey(environ):
                    log.debug(f"Unauthorized api accessed: {environ['PATH_INFO']}")
                    return_dict = {}
                    return_dict[u'error'] = {u'__type': u'Authorization Error',
                                             u'message': toolkit._(u'Access denied')}
                    return_dict[u'success'] = False
                    response_msg = json.dumps(return_dict, for_json=True).encode('utf8')
                    status = '403 Unauthorized'
                    headers = [('Content-type',  'application/json;charset=utf-8')]
                    start_response(status, headers)
                    # Return now as we want to end the request
                    return [response_msg]
            else:
                # The only pages unauthorized users have access to are below
                # service login, saml2login, acs (SAML Assertion Consumer Service), user unauthorised and logout pages
                # But still allow unauthorized access to assets
                unauthorized_pages_allowed = toolkit.aslist(toolkit.config.get('ckanext.qdes_access.unauthorized_pages_allowed', ''))
                if environ['PATH_INFO'] not in unauthorized_pages_allowed \
                        and not environ['PATH_INFO'].startswith('/base') \
                        and not environ['PATH_INFO'].startswith('/webassets') \
                        and not environ['PATH_INFO'].startswith('/images') \
                        and not environ['PATH_INFO'].startswith('/css') \
                        and not environ['PATH_INFO'].startswith('/js') \
                        and not environ['PATH_INFO'].startswith('/_debug') \
                        and not environ['PATH_INFO'].startswith('/uploads'):

                    log.debug(f"Unauthorized page accessed: {environ['PATH_INFO']}")
                    # Status code needs to be 3xx (redirection) for Location header to be used
                    status = "302 Unauthorized"
                    location = toolkit.config.get('ckanext.qdes_access.unauthorized_redirect_location', '/user/saml2login')
                    headers = [('Location', location),
                               ('Content-Length', '0')]
                    log.debug(f"Redirecting to: {location}")
                    start_response(status, headers)
                    # Return now as we want to end the request
                    return []

        return self.app(environ, start_response)
def issues_enabled(dataset):
    datasets_with_issues_enabled = set(toolkit.aslist(
        config.get('ckanext.issues.enabled_for_datasets')
    ))
    # if the config option 'ckanext.issues.enabled_for_dataset' is
    # set with a list of datasets, only enabled for the listed datasets
    if datasets_with_issues_enabled:
        if dataset['name'] in datasets_with_issues_enabled:
            return True
    else:
        extras = dataset.get('extras')
        if extras is not None:
            for extra in extras:
                if extra.get('key') == 'issues_enabled':
                    return toolkit.asbool(extra.get('value'))
        else:
            return toolkit.asbool(config.get('ckanext.issues.enabled_per_dataset_default', True))
Пример #29
0
def run(ctx, host, port, disable_reloader, threaded, extra_files, processes,
        ssl_cert, ssl_key):
    u"""Runs the Werkzeug development server"""

    # Reloading
    use_reloader = not disable_reloader
    config_extra_files = tk.aslist(
        config.get(u"ckan.devserver.watch_patterns"))
    extra_files = list(extra_files) + [config[u"__file__"]
                                       ] + config_extra_files

    # Threads and processes
    threaded = threaded or tk.asbool(config.get(u"ckan.devserver.threaded"))
    processes = processes or tk.asint(
        config.get(u"ckan.devserver.multiprocess", 1))
    if threaded and processes > 1:
        tk.error_shout(u"Cannot have a multithreaded and multi process server")
        raise click.Abort()

    # SSL
    cert_file = ssl_cert or config.get('ckan.devserver.ssl_cert')
    key_file = ssl_key or config.get('ckan.devserver.ssl_key')

    if cert_file and key_file:
        if cert_file == key_file == 'adhoc':
            ssl_context = 'adhoc'
        else:
            ssl_context = (ssl_cert, ssl_key)
    else:
        ssl_context = None

    log.info(u"Running CKAN on {scheme}://{host}:{port}".format(
        scheme='https' if ssl_context else 'http', host=host, port=port))

    run_simple(
        host,
        port,
        ctx.obj.app,
        use_reloader=use_reloader,
        use_evalex=True,
        threaded=threaded,
        processes=processes,
        extra_files=extra_files,
        ssl_context=ssl_context,
    )
Пример #30
0
def is_resource_updatable(id, package_id=None):
    if package_id:
        pkg = model.Package.get(id)
    else:
        pkg = model.Resource.get(id).package

    org = pkg.get_groups('organization')[0]
    org_names = set(
        map(attrgetter('name'), org.get_parent_groups('organization')))
    include_owner = tk.asbool(
        tk.config.get('ckanext.spc.orgs_with_publications_include_root'))
    if include_owner:
        org_names.add(org.name)

    restricted_orgs = set(
        tk.aslist(tk.config.get('ckanext.spc.orgs_with_publications')))

    if org_names & restricted_orgs:
        return pkg.private
    return True
Пример #31
0
def get_user_details(sid: str) -> Optional[Details]:
    """Fetch user data from Drupal's database."""
    import ckanext.drupal_idp.drupal as drupal

    adapter = drupal.get_adapter(
        tk.config.get(CONFIG_DRUPAL_VERSION, DEFAULT_DRUPAL_VERSION)
    )
    user = adapter.get_user_by_sid(sid)
    # check if session has username,
    # otherwise is unauthenticated user session

    if not user:
        return
    details_data = DetailsData(**user)
    roles = adapter.get_user_roles(user.id)
    details_data["avatar"] = adapter.get_avatar(user.id)
    details_data["roles"] = roles

    extra_fields = tk.aslist(tk.config.get(CONFIG_EXTRA_FIELDS, DEFAULT_EXTRA_FIELDS))
    details_data["fields"] = adapter.get_fields(user.id, extra_fields)

    return Details(**details_data)
def upload_to_ckan(package_id, filename):

    try:
        resource = registry.action.resource_create(package_id=package_id,
                                                   upload=open(filename, 'rb'))

        email_notification_recipients = t.aslist(
            t.config.get('ckanext.prh_tools.mail_recipients', ''))
        site_title = t.config.get('ckan.site_title', '')
        today = datetime.now().date().isoformat()

        msg = '%(site_title)s - PRH data uploaded %(today)s\n\n%(status)s' % {
            'site_title':
            site_title,
            'today':
            today,
            'status':
            "New data available in https://www.avoindata.fi/data/dataset/%s/resource/%s"
            % (package_id, resource.get('id'))
        }

        for recipient in email_notification_recipients:
            email = {
                'recipient_name': '',
                'recipient_email': recipient,
                'subject': '%s - PRH data uploaded %s' % (site_title, today),
                'body': msg
            }

            try:
                mailer.mail_recipient(**email)
            except mailer.MailerException as e:
                print 'Sending prh data notification to %s failed: %s' % (
                    recipient, e)

    except ValidationError as e:
        print("Resource patch failed: %s" % e.error_summary)
Пример #33
0
    def configure(self, config_):
        results.create_database_table()

        # Update the class variables for the config settings with the values
        # from the config file, *if* they're in the config file.
        config.recheck_resources_after = toolkit.asint(config_.get(
            "ckanext.deadoralive.recheck_resources_after",
            config.recheck_resources_after))
        config.resend_pending_resources_after = toolkit.asint(
            config_.get(
                "ckanext.deadoralive.resend_pending_resources_after",
                config.resend_pending_resources_after))
        config.broken_resource_min_fails = toolkit.asint(
            config_.get(
                "ckanext.deadoralive.broken_resource_min_fails",
                config.broken_resource_min_fails))
        config.broken_resource_min_hours = toolkit.asint(
            config_.get(
                "ckanext.deadoralive.broken_resource_min_hours",
                config.broken_resource_min_hours))
        config.authorized_users = toolkit.aslist(
            config_.get(
                "ckanext.deadoralive.authorized_users",
                config.authorized_users))
Пример #34
0
def dataguide_available_locales():
    return toolkit.aslist(
        config.get('ckanext.eds.available_locales',
                   'en da_DK')
    )
Пример #35
0
from ckanext.publicamundi.lib import uploader
from ckanext.publicamundi.lib import vocabularies

log = logging.getLogger(__name__)

_ = toolkit._
_url = toolkit.url_for
_get_action = toolkit.get_action
_check_access = toolkit.check_access

content_types = {
    'json': 'application/json; charset=utf8',
    'xml': 'application/xml; charset=utf8',
}

resource_formats = toolkit.aslist(
    config.get('ckanext.publicamundi.resource_formats'))


class Controller(BaseController):
    '''Publicamundi-specific api actions'''
    @staticmethod
    def _make_context(**opts):
        ctx = {'model': model, 'session': model.Session, 'api_version': 3}
        if opts:
            ctx.update(opts)
        return ctx

    #
    # Autocomplete helpers
    #
    def _save_new_pending(self, context):
        errors = {}
        error_summary = {}
        params = request.params
        password = str(binascii.b2a_hex(os.urandom(15)))
        data = dict(
            fullname=params['fullname'],
            name=params['name'],
            password1=password,
            password2=password,
            state=model.State.PENDING,
            email=params['email'],
            organization_request=params['organization-for-request'],
            reason_to_access=params['reason-to-access'],
            role=params['role']
        )

        try:
            # captcha.check_recaptcha(request)
            user_dict = logic.get_action('user_create')(context, data)
            if params['organization-for-request']:
                organization = model.Group.get(data['organization_request'])
                sys_admin = model.Session.query(model.User).filter(
                    sqlalchemy.and_(
                        model.User.sysadmin == True,  # noqa
                        model.User.state == 'active'
                    )
                ).first().name
                logic.get_action('organization_member_create')({
                    "user": sys_admin
                }, {
                    "id": organization.id,
                    "username": user_dict['name'],
                    "role": data['role'] if data['role'] else 'member'
                })
                role = data['role'].title() if data['role'] else 'Member'
            else:
                organization = None
            msg = (
                "A request for a new user account has been submitted:"
                "\nUsername: {}"
                "\nName: {}\nEmail: {}\nOrganisation: {}\nRole: {}"
                "\nReason for access: {}"
                "\nThis request can be approved or rejected at {}"
            ).format(
                data['name'], data['fullname'], data['email'],
                organization.display_name if organization else None,
                role if organization else None, data['reason_to_access'],
                g.site_url + h.url_for(
                    controller=(
                        'ckanext.accessrequests.controller'
                        ':AccessRequestsController'
                    ),
                    action='account_requests'
                )
            )
            list_admin_emails = tk.aslist(
                config.get('ckanext.accessrequests.approver_email')
            )
            for admin_email in list_admin_emails:
                try:
                    mailer.mail_recipient(
                        'Admin', admin_email, 'Account request', msg
                    )
                except mailer.MailerException as e:
                    h.flash(
                        "Email error: {0}".format(e.message), allow_html=False
                    )
            h.flash_success(
                'Your request for access to the {0} has been submitted.'.
                format(config.get('ckan.site_title'))
            )
        except ValidationError as e:
            # return validation failures to the form
            if e.error_dict:
                errors = e.error_dict
                error_summary = e.error_summary
            return self.request_account(data, errors, error_summary)
        except CaptchaError:
            errors['Captcha'] = [_(u'Bad Captcha. Please try again.')]
            error_summary['Captcha'] = 'Bad Captcha. Please try again.'
            return self.request_account(data, errors, error_summary)

        h.redirect_to('/')
    def account_requests_management(self):
        ''' Approve or reject an account request
        '''
        action = request.params['action']
        user_id = request.params['id']
        user_name = request.params['name']
        user = model.User.get(user_id)

        context = {
            'model': model,
            'user': c.user,
            'session': model.Session,
        }
        activity_create_context = {
            'model': model,
            'user': user_name,
            'defer_commit': True,
            'ignore_auth': True,
            'session': model.Session
        }
        activity_dict = {'user_id': c.userobj.id, 'object_id': user_id}
        list_admin_emails = tk.aslist(
            config.get('ckanext.accessrequests.approver_email')
        )
        if action == 'forbid':
            object_id_validators['reject new user'] = user_id_exists
            activity_dict['activity_type'] = 'reject new user'
            logic.get_action('activity_create')(
                activity_create_context, activity_dict
            )
            org = logic.get_action('organization_list_for_user')({
                'user': user_name
            }, {
                "permission": "read"
            })
            if org:
                logic.get_action('organization_member_delete')(
                    context, {
                        "id": org[0]['id'],
                        "username": user_name
                    }
                )
            logic.get_action('user_delete')(context, {'id': user_id})
            msg = (
                "Your account request for {0} has been rejected by {1}"
                "\n\nFor further clarification "
                "as to why your request has been "
                "rejected please contact the NSW Flood Data Portal ({2})"
            )
            mailer.mail_recipient(
                user.fullname, user.email, 'Account request',
                msg.format(
                    config.get('ckan.site_title'), c.userobj.fullname,
                    c.userobj.email
                )
            )
            msg = ("User account request for {0} "
                   "has been rejected by {1}"
                   ).format(user.fullname or user_name, c.userobj.fullname)
            for admin_email in list_admin_emails:
                try:
                    mailer.mail_recipient(
                        'Admin', admin_email, 'Account request feedback', msg
                    )
                except mailer.MailerException as e:
                    h.flash(
                        "Email error: {0}".format(e.message), allow_html=False
                    )
        elif action == 'approve':
            user_org = request.params['org']
            user_role = request.params['role']
            object_id_validators['approve new user'] = user_id_exists
            activity_dict['activity_type'] = 'approve new user'
            logic.get_action('activity_create')(
                activity_create_context, activity_dict
            )
            org_display_name, org_role = assign_user_to_org(
                user_id, user_org, user_role, context
            )
            # Send invitation to complete registration
            msg = (
                "User account request for {0} "
                "(Organization : {1}, Role: {2}) "
                "has been approved by {3}"
            ).format(
                user.fullname or user_name, org_display_name, org_role,
                c.userobj.fullname
            )
            for admin_email in list_admin_emails:
                try:
                    mailer.mail_recipient(
                        'Admin', admin_email, 'Account request feedback', msg
                    )
                except mailer.MailerException as e:
                    h.flash(
                        "Email error: {0}".format(e.message), allow_html=False
                    )
            try:
                org_dict = tk.get_action('organization_show')(context, {'id': user_org})
                user.name = user.name
                mailer.send_invite(user, org_dict, user_role)
            except Exception as e:
                log.error('Error emailing invite to user: %s', e)
                abort(500, _('Error: couldn' 't email invite to user'))

        response.status = 200
        return render('user/account_requests_management.html')
Пример #38
0
from ckanext.publicamundi.lib import uploader
from ckanext.publicamundi.lib import vocabularies

log = logging.getLogger(__name__)

_ = toolkit._
_url = toolkit.url_for
_get_action = toolkit.get_action
_check_access = toolkit.check_access

content_types = {
    'json': 'application/json; charset=utf8',
    'xml': 'application/xml; charset=utf8',
}

resource_formats = toolkit.aslist(config.get('ckanext.publicamundi.resource_formats'))

class Controller(BaseController):
    '''Publicamundi-specific api actions'''

    @staticmethod
    def _make_context(**opts):
        ctx = { 
            'model': model, 
            'session': model.Session, 
            'api_version': 3 
        }
        if opts:
            ctx.update(opts)
        return ctx
    
Пример #39
0
def send_harvester_status_emails(ctx, config, dryrun, force, all_harvesters):
    load_config(config or ctx.obj['config'])

    email_notification_recipients = t.aslist(
        t.config.get('ckanext.ytp.harvester_status_recipients', ''))

    if not email_notification_recipients and not dryrun:
        print 'No recipients configured'
        return

    status_opts = {} if not all_harvesters else {
        'include_manual': True,
        'include_never_run': True
    }
    status = get_action('harvester_status')({}, status_opts)

    errored_runs = any(item.get('errors') != 0 for item in status.values())
    running = (item.get('started') for item in status.values()
               if item.get('status') == 'running')
    stuck_runs = any(_elapsed_since(started).days > 1 for started in running)

    if not (errored_runs or stuck_runs) and not force:
        print 'Nothing to report'
        return

    if len(status) == 0:
        print 'No harvesters matching criteria found'
        return

    site_title = t.config.get('ckan.site_title', '')
    today = datetime.now().date().isoformat()

    status_templates = {
        'running':
        '%%(title)-%ds | Running since %%(time)s with %%(errors)d errors',
        'finished':
        '%%(title)-%ds | Finished %%(time)s with %%(errors)d errors',
        'pending': '%%(title)-%ds | Pending since %%(time)s'
    }
    unknown_status_template = '%%(title)-%ds | Unknown status: %%(status)s'
    max_title_length = max(len(title) for title in status)

    def status_string(title, values):
        template = status_templates.get(values.get('status'),
                                        unknown_status_template)
        status = values.get('status')
        time_field = 'finished' if status == 'finished' else 'started'
        return template % max_title_length % {
            'title': title,
            'time': _pretty_time(values.get(time_field)),
            'status': status,
            'errors': values.get('errors')
        }

    msg = '%(site_title)s - Harvester summary %(today)s\n\n%(status)s' % {
        'site_title':
        site_title,
        'today':
        today,
        'status':
        '\n'.join(
            status_string(title, values) for title, values in status.items())
    }

    for recipient in email_notification_recipients:
        email = {
            'recipient_name': recipient,
            'recipient_email': recipient,
            'subject': '%s - Harvester summary %s' % (site_title, today),
            'body': msg
        }

        if dryrun:
            print 'to: %s' % recipient
        else:
            try:
                mailer.mail_recipient(**email)
            except mailer.MailerException as e:
                print 'Sending harvester summary to %s failed: %s' % (
                    recipient, e)

    if dryrun:
        print msg