Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support / require pyramid >= 2.0 #308

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ omit =
substanced/*/evolve.py
substanced/evolution/evolve*.py
substanced/scripts/*.py
substanced/scaffolds/*.py

[coverage:report]
show_missing = true
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
1.0b1 (unreleased)
==================

- Update to use Pyramid >= 2.0.
See https://github.com/Pylons/substanced/pull/308

- Fix password check for users created prior to switching to ``bcrypt``.
See https://github.com/Pylons/substanced/pull/316

Expand Down
6 changes: 2 additions & 4 deletions demos/blog/blog/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import deform.widget

from persistent import Persistent
from pyramid.security import (
Allow,
Everyone,
)
from pyramid.authorization import Allow
from pyramid.authorization import Everyone

from substanced.content import content
from substanced.folder import Folder
Expand Down
4 changes: 1 addition & 3 deletions demos/blog/blog/views/retail.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,7 @@ def __init__(self, context, request):
self.request = request

def _nowtz(self):
now = datetime.datetime.utcnow() # naive
y, mo, d, h, mi, s = now.timetuple()[:6]
return datetime.datetime(y, mo, d, h, mi, s, tzinfo=pytz.utc)
return datetime.datetime.now(datetime.timezone.utc)

def _get_feed_info(self):
context = self.context
Expand Down
10 changes: 9 additions & 1 deletion docs/cataloging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -349,15 +349,23 @@ It is possible to postfilter catalog results using the

.. code-block:: python

from pyramid.authorization import Everyone

...

def get_allowed_to_view(context, request):

catalog = find_catalog(context, 'system')
q = catalog['content_type'].eq('News Item')
resultset = q.execute()

objectmap = find_objectmap(context)
identity = request.identity
effective_principals = [
Everyone, identity["userid"]
] + identity["principals"]
return objectmap.allowed(
resultset.oids, request.effective_principals, 'view')
resultset.oids, effective_principals, 'view')

The result of :meth:`~substanced.objectmap.ObjectMap.allowed` is a generator
which returns oids, so the result must be listified if you intend to index into
Expand Down
6 changes: 5 additions & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[pytest]
addopts = -l --strict
addopts = -l --strict --ignore=substanced/scaffolds
norecursedirs = lib include .tox .git
python_files = test_*.py tests.py
filterwarnings =
ignore::DeprecationWarning:ast
ignore::DeprecationWarning:chameleon
ignore::DeprecationWarning:hypatia
ignore::DeprecationWarning:pkg_resources
ignore::DeprecationWarning:webob
ignore::DeprecationWarning:zodburi
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
README = CHANGES = ''

install_requires = [
'pyramid>=1.5dev,<2.0dev', # route_name argument to resource_url
'pyramid>=2.0dev',
'ZODB',
'hypatia>=0.2', # query objects have intersection/union methods
'venusian>=1.0a3', # pyramid wants this too (prefer_finals...)
Expand Down
16 changes: 15 additions & 1 deletion substanced/catalog/indexes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import hypatia.text
import hypatia.util
from persistent import Persistent
from pyramid.authorization import Everyone
from pyramid.settings import asbool
from pyramid.traversal import resource_path_tuple
from pyramid.interfaces import IRequest
Expand Down Expand Up @@ -408,6 +409,18 @@ def __init__(self, discriminator, family=None):
def document_repr(self, docid, default=None):
return 'N/A'

def _effective_principals(self, request):
identity = request.identity
if identity is None:
return [Everyone]
if isinstance(identity, dict): # assume our security policy
return [
Everyone,
identity["userid"]
] + identity["principals"]
else:
return [Everyone, identity]

def allows(self, principals, permission):
""" ``principals`` may either be 1) a sequence of principal
indentifiers, 2) a single principal identifier, or 3) a Pyramid
Expand All @@ -417,9 +430,10 @@ def allows(self, principals, permission):
``permission`` must be a permission name.
"""
if IRequest.providedBy(principals):
principals = principals.effective_principals
principals = self._effective_principals(principals)
elif not is_nonstr_iter(principals):
principals = (principals,)

return AllowsComparator(self, (principals, permission))

class AllowsComparator(hypatia.query.Comparator):
Expand Down
47 changes: 46 additions & 1 deletion substanced/catalog/tests/test_indexes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import unittest
from unittest import mock

from pyramid import testing

import BTrees
Expand Down Expand Up @@ -616,10 +618,53 @@ def test_document_repr(self):
index = self._makeOne(None)
self.assertEqual(index.document_repr(None), 'N/A')

def test__effective_principals_wo_identity(self):
index = self._makeOne(None)
request = testing.DummyRequest()

sec_pol = testing.DummySecurityPolicy()
with mock.patch("pyramid.security._get_security_policy") as gsp:
gsp.return_value = sec_pol
principals = index._effective_principals(request)

self.assertEqual(principals, ['system.Everyone'])

def test__effective_principals_w_identity_as_dict(self):
index = self._makeOne(None)
request = testing.DummyRequest()

identity = {
"userid": "phred",
"principals": ["buffaloes"],
}
sec_pol = testing.DummySecurityPolicy(identity=identity)
with mock.patch("pyramid.security._get_security_policy") as gsp:
gsp.return_value = sec_pol
principals = index._effective_principals(request)

self.assertEqual(principals, ['system.Everyone', 'phred', 'buffaloes'])

def test__effective_principals_w_identity_as_other(self):
index = self._makeOne(None)
request = testing.DummyRequest()

identity = 'phred'
sec_pol = testing.DummySecurityPolicy(identity=identity)
with mock.patch("pyramid.security._get_security_policy") as gsp:
gsp.return_value = sec_pol
principals = index._effective_principals(request)

self.assertEqual(principals, ['system.Everyone', 'phred'])

def test_allows_request(self):
index = self._makeOne(None)
request = testing.DummyRequest()
q = index.allows(request, 'edit')

sec_pol = testing.DummySecurityPolicy()
with mock.patch("pyramid.security._get_security_policy") as gsp:
gsp.return_value = sec_pol
q = index.allows(request, 'edit')

self.assertEqual(q._value, (['system.Everyone'], 'edit'))

def test_allows_iterable(self):
Expand Down
2 changes: 0 additions & 2 deletions substanced/content/test_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ def test_add_with_meta(self):
def test_create(self):
registry = DummyRegistry()
inst = self._makeOne(registry)
inst._utcnow = lambda *a: 1
content = testing.DummyResource()
inst.content_types['dummy'] = lambda a: content
inst.meta['dummy'] = {}
Expand All @@ -34,7 +33,6 @@ def test_create(self):
def test_create_with_oid(self):
registry = DummyRegistry()
inst = self._makeOne(registry)
inst._utcnow = lambda *a: 1
content = testing.DummyResource()
inst.content_types['dummy'] = lambda a: content
inst.meta['dummy'] = {}
Expand Down
2 changes: 1 addition & 1 deletion substanced/dump/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
alsoProvides,
)
from zope.interface.interface import InterfaceClass
from pyramid.authorization import AllPermissionsList, ALL_PERMISSIONS
from pyramid.request import Request
from pyramid.security import AllPermissionsList, ALL_PERMISSIONS
from pyramid.threadlocal import get_current_registry
from pyramid.traversal import resource_path
from pyramid.util import (
Expand Down
2 changes: 1 addition & 1 deletion substanced/dump/test_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ def _makeOne(self, name, registry):
return ACLDumper(name, registry)

def test_init_adds_yaml_stuff(self):
from pyramid.security import ALL_PERMISSIONS
from pyramid.authorization import ALL_PERMISSIONS
from . import DUMP_ALL_PERMISSIONS
yamlthing = DummyYAMLDumperLoader()
registry = {'yaml_loader':yamlthing, 'yaml_dumper':yamlthing}
Expand Down
3 changes: 1 addition & 2 deletions substanced/locking/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import datetime
import uuid
import pytz

from zope.interface import implementer

Expand Down Expand Up @@ -70,7 +69,7 @@ class UnlockError(LockingError):
"""

def now():
return datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)
return datetime.datetime.now(datetime.timezone.utc)

class LockOwnerSchema(colander.SchemaNode):
title = 'Owner'
Expand Down
16 changes: 8 additions & 8 deletions substanced/locking/tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ def _callFUT(self):
return now()

def test_it(self):
from pytz import UTC
import datetime
result = self._callFUT()
self.assertEqual(result.tzinfo, UTC)
self.assertIs(result.tzinfo, datetime.timezone.utc)

class TestLockOwnerSchema(unittest.TestCase):
def _makeOne(self):
Expand Down Expand Up @@ -212,14 +212,14 @@ def test_ctor(self):
def test_refresh(self):
import datetime
inst = self._makeOne()
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
inst.refresh(when=now)
self.assertEqual(inst.last_refresh, now)

def test_refresh_with_timeout(self):
import datetime
inst = self._makeOne()
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
inst.refresh(timeout=30, when=now)
self.assertEqual(inst.last_refresh, now)
self.assertEqual(inst.timeout, 30)
Expand All @@ -233,7 +233,7 @@ def test_expires_timeout_is_int(self):
import datetime
inst = self._makeOne()
inst.timeout = 30
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
inst.last_refresh = now
self.assertEqual(inst.expires(), now + datetime.timedelta(seconds=30))

Expand All @@ -246,7 +246,7 @@ def test_is_valid_expires_timeout_is_int(self):
import datetime
inst = self._makeOne()
inst.timeout = 30
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
future = now + datetime.timedelta(seconds=60)
inst.last_refresh = now
self.assertTrue(inst.is_valid(now))
Expand All @@ -256,7 +256,7 @@ def test_is_valid_expires_resource_id_exists(self):
import datetime
inst = self._makeOne()
inst.timeout = 30
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
inst.last_refresh = now
inst.__objectmap__ = DummyObjectMap([1])
self.assertTrue(inst.is_valid(now))
Expand All @@ -265,7 +265,7 @@ def test_is_valid_expires_resource_id_notexist(self):
import datetime
inst = self._makeOne()
inst.timeout = 30
now = datetime.datetime.utcnow()
now = datetime.datetime.now(datetime.timezone.utc)
inst.last_refresh = now
inst.__objectmap__ = DummyObjectMap([])
self.assertFalse(inst.is_valid(now))
Expand Down
2 changes: 1 addition & 1 deletion substanced/objectmap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import BTrees
import colander
from persistent import Persistent
from pyramid.security import Allow
from pyramid.authorization import Allow
from pyramid.traversal import (
resource_path_tuple,
find_resource,
Expand Down
2 changes: 1 addition & 1 deletion substanced/objectmap/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pyramid.view import view_defaults
from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.view import view_defaults

from . import (
find_objectmap,
Expand Down
4 changes: 2 additions & 2 deletions substanced/principal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
import colander
import pytz

from pyramid.renderers import render
from pyramid.security import (
from pyramid.authorization import (
Allow,
Everyone,
)
from pyramid.renderers import render
from pyramid.threadlocal import get_current_registry

from pyramid_mailer import get_mailer
Expand Down
2 changes: 1 addition & 1 deletion substanced/principal/subscribers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pyramid.security import Allow
from pyramid.authorization import Allow

from ..event import (
subscribe_added,
Expand Down
2 changes: 1 addition & 1 deletion substanced/principal/tests/test_subscribers.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def test_it_user_has_no_oid(self):
self.assertRaises(AttributeError, self._callFUT, event)

def test_it(self):
from pyramid.security import Allow
from pyramid.authorization import Allow
user = testing.DummyResource()
user.__oid__ = 1
event = testing.DummyResource(object=user, loading=False)
Expand Down
4 changes: 2 additions & 2 deletions substanced/root/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import colander
from zope.interface import implementer

from pyramid.exceptions import ConfigurationError
from pyramid.security import (
from pyramid.authorization import (
Allow,
ALL_PERMISSIONS,
)
from pyramid.exceptions import ConfigurationError

from ..interfaces import IRoot

Expand Down
Loading