Skip to content

Commit

Permalink
[#1995] Merge remote-tracking branch 'origin/master' into HEAD
Browse files Browse the repository at this point in the history
Conflicts:
	ckan/config/environment.py
	ckan/logic/__init__.py
	ckan/logic/auth/create.py
	ckan/logic/auth/update.py
	ckan/logic/validators.py
	ckan/new_authz.py
	ckan/new_tests/helpers.py
	ckan/tests/legacy/functional/api/test_user.py
	ckan/tests/legacy/logic/test_auth.py
  • Loading branch information
wardi committed Mar 18, 2015
2 parents ad81160 + 87742eb commit 3980a57
Show file tree
Hide file tree
Showing 769 changed files with 150,678 additions and 212,131 deletions.
328 changes: 325 additions & 3 deletions CHANGELOG.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions MANIFEST.in
Expand Up @@ -12,6 +12,7 @@ recursive-include ckanext/*/public *
recursive-include ckanext/*/templates *
recursive-include ckanext/*/theme/public *
recursive-include ckanext/*/theme/templates *
include ckanext/datastore/set_permissions.sql

prune .git
include CHANGELOG.txt
Expand Down
12 changes: 6 additions & 6 deletions ckan/__init__.py
@@ -1,18 +1,18 @@
__version__ = '2.3a'
__version__ = '2.4a'

__description__ = 'CKAN Software'
__long_description__ = \
'''CKAN software provides a hub for datasets. The flagship site running CKAN
'''CKAN software provides a hub for datasets. The flagship site running CKAN
is theDataHub.org but it is also used for dozens of other open data websites
run by governments, agencies and citizens.
CKAN provides a place to search for open knowledge resources as well as
register your own - be that a set of Shakespeare's works, a global
population density database, the voting records of MPs, or 30 years of
CKAN provides a place to search for open knowledge resources as well as
register your own - be that a set of Shakespeare's works, a global
population density database, the voting records of MPs, or 30 years of
US patents.
Those familiar with Freshmeat or CPAN can think of CKAN as providing an
analogous service for open data and knowledge.
analogous service for open data and knowledge.
'''
__license__ = 'AGPL'

Expand Down
63 changes: 34 additions & 29 deletions ckan/authz.py
@@ -1,10 +1,3 @@
import sys
import re
from logging import getLogger

from pylons import config
from paste.deploy.converters import asbool

import ckan.plugins as p
import ckan.model as model
from ckan.common import OrderedDict, _, c
Expand Down Expand Up @@ -44,7 +37,7 @@ def _build(self):

module_root = 'ckan.logic.auth'

for auth_module_name in ['get', 'create', 'update', 'delete']:
for auth_module_name in ['get', 'create', 'update', 'delete', 'patch']:
module_path = '%s.%s' % (module_root, auth_module_name,)
try:
module = __import__(module_path)
Expand Down Expand Up @@ -94,7 +87,6 @@ def _build(self):

def clear_auth_functions_cache():
_AuthFunctions.clear()
CONFIG_PERMISSIONS.clear()


def auth_functions_list():
Expand Down Expand Up @@ -374,28 +366,41 @@ def get_user_id_for_username(user_name, allow_none=False):
'roles_that_cascade_to_sub_groups': 'admin',
}

CONFIG_PERMISSIONS = {}


def check_config_permission(permission):
''' Returns the permission configuration, usually True/False '''
# set up perms if not already done
if not CONFIG_PERMISSIONS:
for perm in CONFIG_PERMISSIONS_DEFAULTS:
key = 'ckan.auth.' + perm
default = CONFIG_PERMISSIONS_DEFAULTS[perm]
CONFIG_PERMISSIONS[perm] = config.get(key, default)
if perm == 'roles_that_cascade_to_sub_groups':
# this permission is a list of strings (space separated)
CONFIG_PERMISSIONS[perm] = \
CONFIG_PERMISSIONS[perm].split(' ') \
if CONFIG_PERMISSIONS[perm] else []
else:
# most permissions are boolean
CONFIG_PERMISSIONS[perm] = asbool(CONFIG_PERMISSIONS[perm])
if permission in CONFIG_PERMISSIONS:
return CONFIG_PERMISSIONS[permission]
return False
'''Returns the configuration value for the provided permission
Permission is a string indentifying the auth permission (eg
`anon_create_dataset`), optionally prefixed with `ckan.auth.`.
The possible values for `permission` are the keys of
CONFIG_PERMISSIONS_DEFAULTS. These can be overriden in the config file
by prefixing them with `ckan.auth.`.
Returns the permission value, generally True or False, except on
`roles_that_cascade_to_sub_groups` which is a list of strings.
'''

key = permission.replace('ckan.auth.', '')

if key not in CONFIG_PERMISSIONS_DEFAULTS:
return False

default_value = CONFIG_PERMISSIONS_DEFAULTS.get(key)

config_key = 'ckan.auth.' + key

value = config.get(config_key, default_value)

if key == 'roles_that_cascade_to_sub_groups':
# This permission is set as a list of strings (space separated)
value = value.split() if value else []
else:
value = asbool(value)

return value


@maintain.deprecated('Use auth_is_loggedin_user instead')
def auth_is_registered_user():
Expand Down
35 changes: 27 additions & 8 deletions ckan/config/deployment.ini_tmpl
Expand Up @@ -40,16 +40,19 @@ app_instance_uuid = ${app_instance_uuid}
who.config_file = %(here)s/who.ini
who.log_level = warning
who.log_file = %(cache_dir)s/who_log.ini

# Session timeout (user logged out after period of inactivity, in seconds).
# Inactive by default, so the session doesn't expire.
# who.timeout = 86400

## Database Settings
sqlalchemy.url = postgresql://ckan_default:pass@localhost/ckan_default

#ckan.datastore.write_url = postgresql://ckan_default:pass@localhost/datastore_default
#ckan.datastore.read_url = postgresql://datastore_default:pass@localhost/datastore_default

# Default Postgres' full-text search index language
# PostgreSQL' full-text search parameters
ckan.datastore.default_fts_lang = english
ckan.datastore.default_fts_index_method = gist

## Site Settings

Expand Down Expand Up @@ -78,14 +81,26 @@ ckan.site_id = default
#ckan.simple_search = 1


## CORS Settings

# If cors.origin_allow_all is true, all origins are allowed.
# If false, the cors.origin_whitelist is used.
# ckan.cors.origin_allow_all = true
# cors.origin_whitelist is a space separated list of allowed domains.
# ckan.cors.origin_whitelist = http://example1.com http://example2.com


## Plugins Settings

# Note: Add ``datastore`` to enable the CKAN DataStore
# Add ``datapusher`` to enable DataPusher
# Add ``pdf_view`` to enable the resource views for PDFs
# Add ``resource_proxy`` to enable resorce proxying and get around the
# same origin policy
ckan.plugins = stats text_view recline_view
ckan.plugins = stats text_view image_view recline_view

# Define which views should be created by default
# (plugins must be loaded in ckan.plugins)
ckan.views.default_views = image_view text_view recline_view


## Front-End Settings
Expand Down Expand Up @@ -132,6 +147,10 @@ ckan.feeds.author_link =
#ckan.datapusher.formats = csv xls xlsx tsv application/csv application/vnd.ms-excel application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
#ckan.datapusher.url = http://127.0.0.1:8800/

# Resource Proxy settings
# Preview size limit, default: 1MB
#ckan.resource_proxy.max_file_size = 1 * 1024 * 1024

## Activity Streams Settings

#ckan.activity_streams_enabled = true
Expand All @@ -143,10 +162,10 @@ ckan.hide_activity_from_users = %(ckan.site_id)s

## Email settings

email_to = you@yourdomain.com
error_email_from = paste@localhost
smtp.server = localhost
smtp.starttls = False
#email_to = you@yourdomain.com
#error_email_from = paste@localhost
#smtp.server = localhost
#smtp.starttls = False
#smtp.user = your_username@gmail.com
#smtp.password = your_password
#smtp.mail_from =
Expand Down
5 changes: 5 additions & 0 deletions ckan/config/environment.py
Expand Up @@ -290,6 +290,10 @@ def update_config():
if asbool(config.get('ckan.legacy_templates', 'no')):
# We want the new template path for extra snippets like the
# dataviewer and also for some testing stuff
msg = 'Support for Genshi templates is deprecated and will be removed'\
' in a future release'
log.warn(msg)

template_paths = [legacy_templates_path, jinja2_templates_path]
else:
template_paths = [jinja2_templates_path, legacy_templates_path]
Expand Down Expand Up @@ -362,6 +366,7 @@ def template_loaded(template):

# clear other caches
logic.clear_actions_cache()
logic.clear_validators_cache()
authz.clear_auth_functions_cache()

# Here we create the site user if they are not already in the database
Expand Down
52 changes: 16 additions & 36 deletions ckan/config/middleware.py
Expand Up @@ -18,7 +18,6 @@
from routes.middleware import RoutesMiddleware
from repoze.who.config import WhoConfig
from repoze.who.middleware import PluggableAuthenticationMiddleware
from repoze.who.plugins.auth_tkt import make_plugin as auth_tkt_make_plugin
from fanstatic import Fanstatic

from ckan.plugins import PluginImplementations
Expand All @@ -31,6 +30,7 @@

log = logging.getLogger(__name__)


def make_app(conf, full_stack=True, static_files=True, **app_conf):
"""Create a Pylons WSGI application and return it
Expand Down Expand Up @@ -117,32 +117,18 @@ def make_app(conf, full_stack=True, static_files=True, **app_conf):
who_parser = WhoConfig(conf['here'])
who_parser.parse(open(app_conf['who.config_file']))

if asbool(config.get('openid_enabled', 'true')):
from repoze.who.plugins.openid.identification import OpenIdIdentificationPlugin
# Monkey patches for repoze.who.openid
# Fixes #1659 - enable log-out when CKAN mounted at non-root URL
from ckan.lib import repoze_patch
OpenIdIdentificationPlugin.identify = repoze_patch.identify
OpenIdIdentificationPlugin.redirect_to_logged_in = repoze_patch.redirect_to_logged_in
OpenIdIdentificationPlugin._redirect_to_loginform = repoze_patch._redirect_to_loginform
OpenIdIdentificationPlugin.challenge = repoze_patch.challenge

who_parser.identifiers = [i for i in who_parser.identifiers if \
not isinstance(i, OpenIdIdentificationPlugin)]
who_parser.challengers = [i for i in who_parser.challengers if \
not isinstance(i, OpenIdIdentificationPlugin)]

app = PluggableAuthenticationMiddleware(app,
who_parser.identifiers,
who_parser.authenticators,
who_parser.challengers,
who_parser.mdproviders,
who_parser.request_classifier,
who_parser.challenge_decider,
logging.getLogger('repoze.who'),
logging.WARN, # ignored
who_parser.remote_user_key,
)
app = PluggableAuthenticationMiddleware(
app,
who_parser.identifiers,
who_parser.authenticators,
who_parser.challengers,
who_parser.mdproviders,
who_parser.request_classifier,
who_parser.challenge_decider,
logging.getLogger('repoze.who'),
logging.WARN, # ignored
who_parser.remote_user_key
)

# Establish the Registry for this application
app = RegistryManager(app)
Expand All @@ -155,7 +141,7 @@ def make_app(conf, full_stack=True, static_files=True, **app_conf):
else int(config.get('ckan.static_max_age', 3600))

static_app = StaticURLParser(config['pylons.paths']['static_files'],
cache_max_age=static_max_age)
cache_max_age=static_max_age)
static_parsers = [static_app, app]

storage_directory = uploader.get_storage_path()
Expand All @@ -168,8 +154,7 @@ def make_app(conf, full_stack=True, static_files=True, **app_conf):
if e.errno != 17:
raise

storage_app = StaticURLParser(path,
cache_max_age=static_max_age)
storage_app = StaticURLParser(path, cache_max_age=static_max_age)
static_parsers.insert(0, storage_app)

# Configurable extra static file paths
Expand All @@ -178,7 +163,7 @@ def make_app(conf, full_stack=True, static_files=True, **app_conf):
if public_path.strip():
extra_static_parsers.append(
StaticURLParser(public_path.strip(),
cache_max_age=static_max_age)
cache_max_age=static_max_age)
)
app = Cascade(extra_static_parsers + static_parsers)

Expand All @@ -192,11 +177,6 @@ def make_app(conf, full_stack=True, static_files=True, **app_conf):

return app

def ckan_auth_tkt_make_app(**kw):
if not len(kw.get('secret', '')) or kw.get('secret') == 'somesecret':
kw['secret'] = config['beaker.session.secret']
return auth_tkt_make_plugin(**kw)


class I18nMiddleware(object):
"""I18n Middleware selects the language based on the url
Expand Down
4 changes: 0 additions & 4 deletions ckan/config/routing.py
Expand Up @@ -282,10 +282,6 @@ def make_map():
map.redirect('/groups', '/group')
map.redirect('/groups/{url:.*}', '/group/{url}')

##to get back formalchemy uncomment these lines
##map.connect('/group/new', controller='group_formalchemy', action='new')
##map.connect('/group/edit/{id}', controller='group_formalchemy', action='edit')

# These named routes are used for custom group forms which will use the
# names below based on the group.type ('group' is the default type)
with SubMapper(map, controller='group') as m:
Expand Down
4 changes: 3 additions & 1 deletion ckan/config/solr/schema.xml
Expand Up @@ -97,6 +97,7 @@

<field name="capacity" type="string" indexed="true" stored="true" multiValued="false"/>

<field name="res_name" type="textgen" indexed="true" stored="true" multiValued="true" />
<field name="res_description" type="textgen" indexed="true" stored="true" multiValued="true"/>
<field name="res_format" type="string" indexed="true" stored="true" multiValued="true"/>
<field name="res_url" type="string" indexed="true" stored="true" multiValued="true"/>
Expand Down Expand Up @@ -161,8 +162,9 @@
<copyField source="notes" dest="text"/>
<copyField source="tags" dest="text"/>
<copyField source="groups" dest="text"/>
<copyField source="res_name" dest="text"/>
<copyField source="res_description" dest="text"/>
<copyField source="maintainer" dest="text"/>
<copyField source="author" dest="text"/>

</schema>
</schema>

0 comments on commit 3980a57

Please sign in to comment.