Skip to content

Commit

Permalink
Merge branch 'master' ckan/ckan into 1661-openid
Browse files Browse the repository at this point in the history
  • Loading branch information
brew committed Nov 20, 2014
2 parents eba7f2d + 028fc62 commit d8e1cd6
Show file tree
Hide file tree
Showing 45 changed files with 1,556 additions and 296 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.rst
Expand Up @@ -32,8 +32,13 @@ API changes and deprecations
* Cross-Origin Resource Sharing (CORS) support is no longer enabled by
default. Previously, Access-Control-Allow-* response headers were added for
all requests, with Access-Control-Allow-Origin set to the wildcard value
``*``. To re-enable CORS, use the new ``ckan.cors`` settings detailed in the
Config File Options documentation (:doc:`/maintaining/configuration`)
``*``. To re-enable CORS, use the new ``ckan.cors`` configuration settings
(:ref:`ckan.cors.origin_allow_all` and :ref:`ckan.cors.origin_whitelist`).

* The HttpOnly flag will be set on the authorization cookie by default. For
enhanced security, we recommend using the HttpOnly flag, but this behaviour
can be changed in the ``Repoze.who`` settings detailed in the Config File
Options documentation (:ref:`who.httponly`).

* OpenID support has been removed and is no longer supported.

Expand Down
6 changes: 0 additions & 6 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 Down Expand Up @@ -177,11 +176,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: 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>
2 changes: 1 addition & 1 deletion ckan/config/who.ini
@@ -1,5 +1,5 @@
[plugin:auth_tkt]
use = ckan.config.middleware:ckan_auth_tkt_make_app
use = ckan.lib.auth_tkt:make_plugin
# If no secret key is defined here, beaker.session.secret will be used
#secret = somesecret

Expand Down
36 changes: 0 additions & 36 deletions ckan/controllers/group.py
Expand Up @@ -884,39 +884,3 @@ def _get_group_dict(self, id):
abort(404, _('Group not found'))
except NotAuthorized:
abort(401, _('Unauthorized to read group %s') % id)

def _render_edit_form(self, fs):
# errors arrive in c.error and fs.errors
c.fieldset = fs
return render('group/edit_form.html')

def _update(self, fs, group_name, group_id):
'''
Writes the POST data (associated with a group edit) to the database
@input c.error
'''
validation = fs.validate()
if not validation:
c.form = self._render_edit_form(fs)
raise base.ValidationException(fs)

try:
fs.sync()
except Exception, inst:
model.Session.rollback()
raise
else:
model.Session.commit()

def _update_authz(self, fs):
validation = fs.validate()
if not validation:
c.form = self._render_edit_form(fs)
raise base.ValidationException(fs)
try:
fs.sync()
except Exception, inst:
model.Session.rollback()
raise
else:
model.Session.commit()
4 changes: 2 additions & 2 deletions ckan/controllers/home.py
Expand Up @@ -111,7 +111,7 @@ def index(self):
if msg:
h.flash_notice(msg, allow_html=True)

# START OF DIRTYNESS
# START OF DIRTINESS
def get_group(id):
def _get_group_type(id):
"""
Expand Down Expand Up @@ -178,7 +178,7 @@ def db_to_form_schema(group_type=None):

c.group_package_stuff = dirty_cached_group_stuff

# END OF DIRTYNESS
# END OF DIRTINESS
return base.render('home/index.html', cache_force=True)

def license(self):
Expand Down
3 changes: 0 additions & 3 deletions ckan/controllers/package.py
Expand Up @@ -14,7 +14,6 @@
import ckan.logic as logic
import ckan.lib.base as base
import ckan.lib.maintain as maintain
import ckan.lib.package_saver as package_saver
import ckan.lib.i18n as i18n
import ckan.lib.navl.dictization_functions as dict_fns
import ckan.lib.accept as accept
Expand Down Expand Up @@ -421,8 +420,6 @@ def read(self, id, format='html'):
self._setup_template_variables(context, {'id': id},
package_type=package_type)

package_saver.PackageSaver().render_package(c.pkg_dict, context)

template = self._read_template(package_type)
template = template[:template.index('.') + 1] + format

Expand Down
78 changes: 78 additions & 0 deletions ckan/lib/auth_tkt.py
@@ -0,0 +1,78 @@
import os

from pylons import config
from repoze.who.plugins import auth_tkt as repoze_auth_tkt

_bool = repoze_auth_tkt._bool

import logging
log = logging.getLogger(__name__)


class CkanAuthTktCookiePlugin(repoze_auth_tkt.AuthTktCookiePlugin):

def __init__(self, httponly, *args, **kwargs):
super(CkanAuthTktCookiePlugin, self).__init__(*args, **kwargs)
self.httponly = httponly

def _get_cookies(self, *args, **kwargs):
'''
Override method in superclass to ensure HttpOnly is set appropriately.
'''
super_cookies = super(CkanAuthTktCookiePlugin, self). \
_get_cookies(*args, **kwargs)

cookies = []
for k, v in super_cookies:
replace_with = '; HttpOnly' if self.httponly else ''
v = v.replace('; HttpOnly', '') + replace_with
cookies.append((k, v))

return cookies


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 specific: get secret from beaker setting if necessary
if secret is None or secret == 'somesecret':
secret = config['beaker.session.secret']

# Set httponly based on config value. Default is True
httponly = config.get('who.httponly', True)

# Set secure based on config value. Default is False
secure = config.get('who.secure', False)

# back to repoze boilerplate
if (secret is None and secretfile is None):
raise ValueError("One of 'secret' or 'secretfile' must not be None.")
if (secret is not None and secretfile is not None):
raise ValueError("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("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(_bool(httponly),
secret,
cookie_name,
_bool(secure),
_bool(include_ip),
timeout,
reissue_time,
userid_checker)
return plugin
22 changes: 16 additions & 6 deletions ckan/lib/cli.py
Expand Up @@ -106,7 +106,7 @@ class CkanCommand(paste.script.command.Command):
'''
parser = paste.script.command.Command.standard_parser(verbose=True)
parser.add_option('-c', '--config', dest='config',
default='development.ini', help='Config file to use.')
help='Config file to use.')
parser.add_option('-f', '--file',
action='store',
dest='file_path',
Expand All @@ -116,12 +116,22 @@ class CkanCommand(paste.script.command.Command):

def _get_config(self):
from paste.deploy import appconfig
if not self.options.config:
msg = 'No config file supplied'
raise self.BadCommand(msg)
self.filename = os.path.abspath(self.options.config)

if self.options.config:
self.filename = os.path.abspath(self.options.config)
config_source = '-c parameter'
elif os.environ.get('CKAN_INI'):
self.filename = os.environ.get('CKAN_INI')
config_source = '$CKAN_INI'
else:
self.filename = 'development.ini'
config_source = 'default value'

if not os.path.exists(self.filename):
raise AssertionError('Config filename %r does not exist.' % self.filename)
msg = 'Config file not found: %s' % self.filename
msg += '\n(Given by: %s)' % config_source
raise self.BadCommand(msg)

fileConfig(self.filename)
return appconfig('config:' + self.filename)

Expand Down
116 changes: 0 additions & 116 deletions ckan/lib/package_saver.py

This file was deleted.

8 changes: 8 additions & 0 deletions ckan/lib/plugins.py
Expand Up @@ -221,6 +221,8 @@ def show_package_schema(self):
return ckan.logic.schema.default_show_package_schema()

def setup_template_variables(self, context, data_dict):
from ckan.lib.helpers import render_markdown

authz_fn = logic.get_action('group_list_authz')
c.groups_authz = authz_fn(context, data_dict)
data_dict.update({'available_only': True})
Expand All @@ -235,6 +237,12 @@ def setup_template_variables(self, context, data_dict):

if c.pkg:
c.related_count = c.pkg.related_count
c.pkg_notes_formatted = render_markdown(c.pkg.notes)

if context.get('revision_id') or context.get('revision_date'):
c.pkg_revision_id = c.pkg_dict[u'revision_id']
c.pkg_revision_timestamp = c.pkg_dict[u'revision_timestamp']
c.pkg_revision_not_latest = c.pkg_dict[u'revision_id'] != c.pkg.revision.id

## This is messy as auths take domain object not data_dict
context_pkg = context.get('package', None)
Expand Down

0 comments on commit d8e1cd6

Please sign in to comment.