From a7e625785f65c41e5a6dc017b31bd0d74821474e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 31 May 2011 14:40:05 -0400 Subject: the canonical import location for HTTP exceptions/responses is now pyramid.response --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 2 +- docs/tutorials/wiki2/src/authorization/tutorial/login.py | 2 +- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 05183d3d4..42013622c 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -39,7 +39,7 @@ def main(global_config, **settings): config.add_view('tutorial.views.edit_page', route_name='edit_page', renderer='tutorial:templates/edit.pt', permission='edit') config.add_view('tutorial.login.login', - context='pyramid.exceptions.Forbidden', + context='pyramid.response.HTTPForbidden', renderer='tutorial:templates/login.pt') return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/login.py b/docs/tutorials/wiki2/src/authorization/tutorial/login.py index 7a1d1f663..2bc8a7201 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/login.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/login.py @@ -1,4 +1,4 @@ -from pyramid.httpexceptions import HTTPFound +from pyramid.response import HTTPFound from pyramid.security import remember from pyramid.security import forget from pyramid.url import route_url diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index 5abd8391e..ed441295c 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -2,7 +2,7 @@ import re from docutils.core import publish_parts -from pyramid.httpexceptions import HTTPFound +from pyramid.response import HTTPFound from pyramid.security import authenticated_userid from pyramid.url import route_url -- cgit v1.2.3 From 99edc51a3b05309c7f5d98ff96289ec51b1d7660 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 11 Jun 2011 05:35:27 -0400 Subject: - Pyramid now expects Response objects to have a __call__ method which implements the WSGI application interface instead of the three webob attrs status, headerlist and app_iter. Backwards compatibility exists for code which returns response objects that do not have a __call__. - pyramid.response.Response is no longer an exception (and therefore cannot be raised in order to generate a response). - Changed my mind about moving stuff from pyramid.httpexceptions to pyramid.response. The stuff I moved over has been moved back to pyramid.httpexceptions. --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 2 +- docs/tutorials/wiki2/src/authorization/tutorial/login.py | 2 +- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 42013622c..4cd84eda5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -39,7 +39,7 @@ def main(global_config, **settings): config.add_view('tutorial.views.edit_page', route_name='edit_page', renderer='tutorial:templates/edit.pt', permission='edit') config.add_view('tutorial.login.login', - context='pyramid.response.HTTPForbidden', + context='pyramid.httpexceptions.HTTPForbidden', renderer='tutorial:templates/login.pt') return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/login.py b/docs/tutorials/wiki2/src/authorization/tutorial/login.py index 2bc8a7201..7a1d1f663 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/login.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/login.py @@ -1,4 +1,4 @@ -from pyramid.response import HTTPFound +from pyramid.httpexceptions import HTTPFound from pyramid.security import remember from pyramid.security import forget from pyramid.url import route_url diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index ed441295c..5abd8391e 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -2,7 +2,7 @@ import re from docutils.core import publish_parts -from pyramid.response import HTTPFound +from pyramid.httpexceptions import HTTPFound from pyramid.security import authenticated_userid from pyramid.url import route_url -- cgit v1.2.3 From aec6b29b42ad2acf0c9febd884ae9db1316022c5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 12 Jul 2011 19:52:26 -0400 Subject: - The ``pyramid_routesalchemy`` and ``pyramid_alchemy`` scaffolds inappropriately used ``DBSession.rollback()`` instead of ``transaction.abort()`` in one place. - Wiki2 (SQLAlchemy + URL Dispatch) tutorial ``models.initialize_sql`` didn't match the ``pyramid_routesalchemy`` scaffold function of the same name; it didn't get synchronized when it was changed in the scaffold. --- docs/tutorials/wiki2/src/authorization/tutorial/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py index 53c6d1122..832545cb1 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py @@ -41,7 +41,7 @@ def initialize_sql(engine): transaction.commit() except IntegrityError: # already created - pass + transaction.abort() class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), -- cgit v1.2.3 From 39e88a1f2903f840feeff77e572c7bf3efebb875 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 21 Jul 2011 23:08:31 -0400 Subject: - Change all scaffolding templates that point to docs.pylonsproject.org to use ``/projects/pyramid/current`` rather than ``/projects/pyramid/dev``. --- .../src/authorization/tutorial/templates/mytemplate.pt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt index d98420680..efe581b59 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -31,7 +31,7 @@

Search documentation

-
+
@@ -43,22 +43,22 @@ Pylons Website
  • - Narrative Documentation + Narrative Documentation
  • - API Documentation + API Documentation
  • - Tutorials + Tutorials
  • - Change History + Change History
  • - Sample Applications + Sample Applications
  • - Support and Development + Support and Development
  • IRC Channel -- cgit v1.2.3 From 875ded31e7fdd0c85d1c91458248581b9dd729d7 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sat, 30 Jul 2011 01:50:24 -0600 Subject: Updated all of the docs to reflect the new pyramid.* settings prefix. --- docs/tutorials/wiki2/src/authorization/development.ini | 12 ++++++------ docs/tutorials/wiki2/src/authorization/production.ini | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 3b615f635..bd71cdba5 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -1,11 +1,11 @@ [app:tutorial] use = egg:tutorial -reload_templates = true -debug_authorization = false -debug_notfound = false -debug_routematch = false -debug_templates = true -default_locale_name = en +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.debug_templates = true +pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 0fdc38811..ed8eadacc 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -1,11 +1,11 @@ [app:tutorial] use = egg:tutorial -reload_templates = false -debug_authorization = false -debug_notfound = false -debug_routematch = false -debug_templates = false -default_locale_name = en +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.debug_templates = false +pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.db [filter:weberror] -- cgit v1.2.3 From 449c2ddc4245eb1457393acdaed122c4d4fb3fa7 Mon Sep 17 00:00:00 2001 From: Blaise Laflamme Date: Sun, 31 Jul 2011 02:02:52 -0400 Subject: updated wiki tutorials css --- docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css | 4 ++-- .../wiki2/src/authorization/tutorial/templates/mytemplate.pt | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css index fd1914d8d..c54499ddd 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css @@ -23,7 +23,7 @@ h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "Nobile","Lucida Grande",Lucida,Verdana,sans-serif;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;} a{color:#1b61d6;text-decoration:none;} a:hover{color:#e88f00;text-decoration:underline;} body h1, @@ -31,7 +31,7 @@ body h2, body h3, body h4, body h5, -body h6{font-family:"Neuton","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} #wrap{min-height:100%;} #header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} #header{background:#000000;top:0;font-size:14px;} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt index efe581b59..14b88d16a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -6,8 +6,9 @@ + + - -- cgit v1.2.3 From efd07ccf6889e965f67b1dd0ef1a09f0efacbf2f Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 11 Aug 2011 23:38:34 -0400 Subject: fix docs, scaffolds, and tutorials to use pyramid.includes --- docs/tutorials/wiki2/src/authorization/development.ini | 9 +++------ docs/tutorials/wiki2/src/authorization/production.ini | 6 +----- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index bd71cdba5..f93a88e6b 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -6,18 +6,15 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en +pyramid.includes = pyramid_debugtoolbar + pyramid_tm + sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] pipeline = - egg:WebError#evalerror - tm tutorial -[filter:tm] -use = egg:repoze.tm2#tm -commit_veto = repoze.tm:default_commit_veto - [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index ed8eadacc..f7b742cb9 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -6,6 +6,7 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en +pyramid.includes = pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db [filter:weberror] @@ -22,14 +23,9 @@ debug = false ;smtp_use_tls = ;error_message = -[filter:tm] -use = egg:repoze.tm2#tm -commit_veto = repoze.tm:default_commit_veto - [pipeline:main] pipeline = weberror - tm tutorial [server:main] -- cgit v1.2.3 From 391402e63c1257ede0069f220ed5a1cca1b94a9b Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 13 Aug 2011 01:00:39 -0400 Subject: - Projects created via a scaffold no longer depend on the ``WebError`` package at all; configuration in the ``production.ini`` file which used to require its ``error_catcher`` middleware has been removed. Configuring error catching / email sending is now the domain of the ``pyramid_exclog`` package (see https://docs.pylonsproject.org/projects/pyramid_exclog/dev/). --- docs/tutorials/wiki2/src/authorization/production.ini | 16 +--------------- docs/tutorials/wiki2/src/authorization/setup.py | 4 ++-- 2 files changed, 3 insertions(+), 17 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index f7b742cb9..45ef791b7 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -7,25 +7,11 @@ pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en pyramid.includes = pyramid_tm -sqlalchemy.url = sqlite:///%(here)s/tutorial.db -[filter:weberror] -use = egg:WebError#error_catcher -debug = false -;error_log = -;show_exceptions_in_wsgi_errors = true -;smtp_server = localhost -;error_email = janitor@example.com -;smtp_username = janitor -;smtp_password = "janitor's password" -;from_address = paste@localhost -;error_subject_prefix = "Pyramid Error" -;smtp_use_tls = -;error_message = +sqlalchemy.url = sqlite:///%(here)s/tutorial.db [pipeline:main] pipeline = - weberror tutorial [server:main] diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index ae9869d50..785d61326 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -11,9 +11,9 @@ requires = [ 'pyramid', 'SQLAlchemy', 'transaction', - 'repoze.tm2>=1.0b1', # default_commit_veto + 'pyramid_tm', + 'pyramid_debugtoolbar', 'zope.sqlalchemy', - 'WebError', 'docutils', ] -- cgit v1.2.3 From 42d31c1c6355a7d6c72393ca668d7d200a994da3 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 14 Aug 2011 14:26:10 -0400 Subject: - All tutorials now use - The ``route_url``, ``route_path``, ``resource_url``, ``static_url``, and ``current_route_url`` methods of the request rather than the function variants imported from ``pyramid.url``. --- .../wiki2/src/authorization/tutorial/login.py | 5 ++--- .../wiki2/src/authorization/tutorial/views.py | 23 +++++++++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/login.py b/docs/tutorials/wiki2/src/authorization/tutorial/login.py index 7a1d1f663..5a825d8d6 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/login.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/login.py @@ -1,12 +1,11 @@ from pyramid.httpexceptions import HTTPFound from pyramid.security import remember from pyramid.security import forget -from pyramid.url import route_url from tutorial.security import USERS def login(request): - login_url = route_url('login', request) + login_url = request.route_url('login') referrer = request.url if referrer == login_url: referrer = '/' # never use the login form itself as came_from @@ -33,6 +32,6 @@ def login(request): def logout(request): headers = forget(request) - return HTTPFound(location = route_url('view_wiki', request), + return HTTPFound(location = request.route_url('view_wiki'), headers = headers) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index e0b84971d..fc85d4585 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -4,7 +4,6 @@ from docutils.core import publish_parts from pyramid.httpexceptions import HTTPFound, HTTPNotFound from pyramid.security import authenticated_userid -from pyramid.url import route_url from tutorial.models import DBSession from tutorial.models import Page @@ -13,8 +12,8 @@ from tutorial.models import Page wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") def view_wiki(request): - return HTTPFound(location = route_url('view_page', request, - pagename='FrontPage')) + return HTTPFound(location = request.route_url('view_page', + pagename='FrontPage')) def view_page(request): pagename = request.matchdict['pagename'] @@ -27,15 +26,15 @@ def view_page(request): word = match.group(1) exists = session.query(Page).filter_by(name=word).all() if exists: - view_url = route_url('view_page', request, pagename=word) + view_url = request.route_url('view_page', pagename=word) return '%s' % (view_url, word) else: - add_url = route_url('add_page', request, pagename=word) + add_url = request.route_url('add_page', pagename=word) return '%s' % (add_url, word) content = publish_parts(page.data, writer_name='html')['html_body'] content = wikiwords.sub(check, content) - edit_url = route_url('edit_page', request, pagename=pagename) + edit_url = request.route_url('edit_page', pagename=pagename) logged_in = authenticated_userid(request) return dict(page=page, content=content, edit_url=edit_url, logged_in=logged_in) @@ -47,9 +46,9 @@ def add_page(request): body = request.params['body'] page = Page(name, body) session.add(page) - return HTTPFound(location = route_url('view_page', request, - pagename=name)) - save_url = route_url('add_page', request, pagename=name) + return HTTPFound(location = request.route_url('view_page', + pagename=name)) + save_url = request.route_url('add_page', pagename=name) page = Page('', '') logged_in = authenticated_userid(request) return dict(page=page, save_url=save_url, logged_in=logged_in) @@ -61,12 +60,12 @@ def edit_page(request): if 'form.submitted' in request.params: page.data = request.params['body'] session.add(page) - return HTTPFound(location = route_url('view_page', request, - pagename=name)) + return HTTPFound(location = request.route_url('view_page', + pagename=name)) logged_in = authenticated_userid(request) return dict( page=page, - save_url = route_url('edit_page', request, pagename=name), + save_url = request.route_url('edit_page', pagename=name), logged_in = logged_in, ) -- cgit v1.2.3 From 3d338ea5737b7c113b17120b40684e2694cf3fa9 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 22 Aug 2011 02:16:55 -0400 Subject: - Use [app:main] instead of a pipeline in all scaffolds and tutorials and narrative docs. - Break out awkward description of PasteDeploy entry points from project chapter into its own Paste chapter. --- docs/tutorials/wiki2/src/authorization/development.ini | 6 +----- docs/tutorials/wiki2/src/authorization/production.ini | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index f93a88e6b..799ce7161 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -1,4 +1,4 @@ -[app:tutorial] +[app:main] use = egg:tutorial pyramid.reload_templates = true pyramid.debug_authorization = false @@ -11,10 +11,6 @@ pyramid.includes = pyramid_debugtoolbar sqlalchemy.url = sqlite:///%(here)s/tutorial.db -[pipeline:main] -pipeline = - tutorial - [server:main] use = egg:Paste#http host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 45ef791b7..df91d0b49 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -1,4 +1,4 @@ -[app:tutorial] +[app:main] use = egg:tutorial pyramid.reload_templates = false pyramid.debug_authorization = false @@ -10,10 +10,6 @@ pyramid.includes = pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db -[pipeline:main] -pipeline = - tutorial - [server:main] use = egg:Paste#http host = 0.0.0.0 -- cgit v1.2.3 From d00fa00e0ee116cce61f157b24b3924d38a352a5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 6 Sep 2011 23:14:18 -0400 Subject: prep for 1.2a6 --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 4cd84eda5..cca52fdfe 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -19,7 +19,7 @@ def main(global_config, **settings): root_factory='tutorial.models.RootFactory', authentication_policy=authn_policy, authorization_policy=authz_policy) - config.add_static_view('static', 'tutorial:static') + config.add_static_view('static', 'tutorial:static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') -- cgit v1.2.3 From cfb2b5596b8ef366aeef3bce5b61eafc7a2f175d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 6 Oct 2011 03:05:29 -0400 Subject: remove all reference to the paster command-line utility --- docs/tutorials/wiki2/src/authorization/development.ini | 2 +- docs/tutorials/wiki2/src/authorization/production.ini | 2 +- docs/tutorials/wiki2/src/authorization/setup.py | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 799ce7161..d1e262324 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -12,7 +12,7 @@ pyramid.includes = pyramid_debugtoolbar sqlalchemy.url = sqlite:///%(here)s/tutorial.db [server:main] -use = egg:Paste#http +use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index df91d0b49..ac02acf3f 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -11,7 +11,7 @@ pyramid.includes = pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db [server:main] -use = egg:Paste#http +use = egg:pyramid#wsgiref host = 0.0.0.0 port = 6543 diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 785d61326..439a86923 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -43,6 +43,5 @@ setup(name='tutorial', [paste.app_factory] main = tutorial:main """, - paster_plugins=['pyramid'], ) -- cgit v1.2.3 From 5edd54f05b05330fa6e899a1bb1650cc7a2df33c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 27 Nov 2011 04:08:20 -0500 Subject: - The SQLAlchemy Wiki tutorial has been updated. It now uses ``@view_config`` decorators and an explicit database population script. Closes #359. --- docs/tutorials/wiki2/src/authorization/README.txt | 3 - .../wiki2/src/authorization/development.ini | 8 ++- .../wiki2/src/authorization/production.ini | 1 + docs/tutorials/wiki2/src/authorization/setup.py | 3 +- .../wiki2/src/authorization/tutorial/__init__.py | 25 ++----- .../wiki2/src/authorization/tutorial/login.py | 37 ----------- .../wiki2/src/authorization/tutorial/models.py | 37 ++++------- .../src/authorization/tutorial/scripts/__init__.py | 1 + .../src/authorization/tutorial/scripts/populate.py | 35 ++++++++++ .../wiki2/src/authorization/tutorial/security.py | 1 - .../wiki2/src/authorization/tutorial/tests.py | 23 +++++-- .../wiki2/src/authorization/tutorial/views.py | 76 ++++++++++++++++++---- 12 files changed, 145 insertions(+), 105 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/login.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/scripts/__init__.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt index d41f7f90f..6f851e9b7 100644 --- a/docs/tutorials/wiki2/src/authorization/README.txt +++ b/docs/tutorials/wiki2/src/authorization/README.txt @@ -1,4 +1 @@ tutorial README - - - diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index d1e262324..4f7493cba 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -1,5 +1,6 @@ [app:main] use = egg:tutorial + pyramid.reload_templates = true pyramid.debug_authorization = false pyramid.debug_notfound = false @@ -19,7 +20,7 @@ port = 6543 # Begin logging configuration [loggers] -keys = root, sqlalchemy +keys = root, tutorial, sqlalchemy [handlers] keys = console @@ -31,6 +32,11 @@ keys = generic level = INFO handlers = console +[logger_tutorial] +level = DEBUG +handlers = +qualname = tutorial + [logger_sqlalchemy] level = INFO handlers = diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index ac02acf3f..53eaf20a1 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -1,5 +1,6 @@ [app:main] use = egg:tutorial + pyramid.reload_templates = false pyramid.debug_authorization = false pyramid.debug_notfound = false diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 439a86923..09769bfff 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -42,6 +42,7 @@ setup(name='tutorial', entry_points = """\ [paste.app_factory] main = tutorial:main + [console_scripts] + populate_tutorial = tutorial.scripts.populate:main """, ) - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index cca52fdfe..04dd5fe82 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -4,14 +4,15 @@ from pyramid.authorization import ACLAuthorizationPolicy from sqlalchemy import engine_from_config -from tutorial.models import initialize_sql from tutorial.security import groupfinder +from .models import DBSession + def main(global_config, **settings): - """ This function returns a WSGI application. + """ This function returns a Pyramid WSGI application. """ engine = engine_from_config(settings, 'sqlalchemy.') - initialize_sql(engine) + DBSession.configure(bind=engine) authn_policy = AuthTktAuthenticationPolicy( 'sosecret', callback=groupfinder) authz_policy = ACLAuthorizationPolicy() @@ -19,27 +20,13 @@ def main(global_config, **settings): root_factory='tutorial.models.RootFactory', authentication_policy=authn_policy, authorization_policy=authz_policy) - config.add_static_view('static', 'tutorial:static', cache_max_age=3600) - + config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') config.add_route('logout', '/logout') config.add_route('view_page', '/{pagename}') config.add_route('add_page', '/add_page/{pagename}') config.add_route('edit_page', '/{pagename}/edit_page') - - config.add_view('tutorial.views.view_wiki', route_name='view_wiki') - config.add_view('tutorial.login.login', route_name='login', - renderer='tutorial:templates/login.pt') - config.add_view('tutorial.login.logout', route_name='logout') - config.add_view('tutorial.views.view_page', route_name='view_page', - renderer='tutorial:templates/view.pt') - config.add_view('tutorial.views.add_page', route_name='add_page', - renderer='tutorial:templates/edit.pt', permission='edit') - config.add_view('tutorial.views.edit_page', route_name='edit_page', - renderer='tutorial:templates/edit.pt', permission='edit') - config.add_view('tutorial.login.login', - context='pyramid.httpexceptions.HTTPForbidden', - renderer='tutorial:templates/login.pt') + config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/login.py b/docs/tutorials/wiki2/src/authorization/tutorial/login.py deleted file mode 100644 index 5a825d8d6..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/login.py +++ /dev/null @@ -1,37 +0,0 @@ -from pyramid.httpexceptions import HTTPFound -from pyramid.security import remember -from pyramid.security import forget - -from tutorial.security import USERS - -def login(request): - login_url = request.route_url('login') - referrer = request.url - if referrer == login_url: - referrer = '/' # never use the login form itself as came_from - came_from = request.params.get('came_from', referrer) - message = '' - login = '' - password = '' - if 'form.submitted' in request.params: - login = request.params['login'] - password = request.params['password'] - if USERS.get(login) == password: - headers = remember(request, login) - return HTTPFound(location = came_from, - headers = headers) - message = 'Failed login' - - return dict( - message = message, - url = request.application_url + '/login', - came_from = came_from, - login = login, - password = password, - ) - -def logout(request): - headers = forget(request) - return HTTPFound(location = request.route_url('view_wiki'), - headers = headers) - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py index 832545cb1..c3bdcbea5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py @@ -1,17 +1,20 @@ -import transaction +from pyramid.security import ( + Allow, + Everyone, + ) -from pyramid.security import Allow -from pyramid.security import Everyone +from sqlalchemy import ( + Column, + Integer, + Text, + ) -from sqlalchemy import Column -from sqlalchemy import Integer -from sqlalchemy import Text - -from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import scoped_session -from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm import ( + scoped_session, + sessionmaker, + ) from zope.sqlalchemy import ZopeTransactionExtension @@ -29,20 +32,6 @@ class Page(Base): self.name = name self.data = data -def initialize_sql(engine): - DBSession.configure(bind=engine) - Base.metadata.bind = engine - Base.metadata.create_all(engine) - try: - transaction.begin() - session = DBSession() - page = Page('FrontPage', 'This is the front page') - session.add(page) - transaction.commit() - except IntegrityError: - # already created - transaction.abort() - class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), (Allow, 'group:editors', 'edit') ] diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/__init__.py @@ -0,0 +1 @@ +# package diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py new file mode 100644 index 000000000..981adff38 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py @@ -0,0 +1,35 @@ +import os +import sys +import transaction + +from sqlalchemy import engine_from_config + +from pyramid.paster import ( + get_appsettings, + setup_logging, + ) + +from ..models import ( + DBSession, + Page, + Base, + ) + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + +def main(argv=sys.argv, settings=None): + if len(argv) != 2: + usage(argv) + config_uri = argv[1] + setup_logging(config_uri) + settings = get_appsettings(config_uri) + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = Page('FrontPage', 'This is the front page') + DBSession.add(model) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security.py b/docs/tutorials/wiki2/src/authorization/tutorial/security.py index cfd13071e..d88c9c71f 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/security.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security.py @@ -5,4 +5,3 @@ GROUPS = {'editor':['group:editors']} def groupfinder(userid, request): if userid in USERS: return GROUPS.get(userid, []) - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index 332031ba4..31d2dc6d5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -1,15 +1,20 @@ import unittest - +import transaction from pyramid import testing def _initTestingDB(): - from tutorial.models import DBSession - from tutorial.models import Base from sqlalchemy import create_engine + from tutorial.models import ( + DBSession, + Page, + Base + ) engine = create_engine('sqlite://') - DBSession.configure(bind=engine) - Base.metadata.bind = engine Base.metadata.create_all(engine) + DBSession.configure(bind=engine) + with transaction.manager: + model = Page('FrontPage', 'This is the front page') + DBSession.add(model) return DBSession def _registerRoutes(config): @@ -20,14 +25,16 @@ def _registerRoutes(config): class ViewWikiTests(unittest.TestCase): def setUp(self): self.config = testing.setUp() + self.session = _initTestingDB() def tearDown(self): + self.session.remove() testing.tearDown() def _callFUT(self, request): from tutorial.views import view_wiki return view_wiki(request) - + def test_it(self): _registerRoutes(self.config) request = testing.DummyRequest() @@ -40,6 +47,7 @@ class ViewPageTests(unittest.TestCase): self.config = testing.setUp() def tearDown(self): + self.session.remove() testing.tearDown() def _callFUT(self, request): @@ -121,7 +129,8 @@ class EditPageTests(unittest.TestCase): self.session.add(page) info = self._callFUT(request) self.assertEqual(info['page'], page) - self.assertEqual(info['save_url'], 'http://example.com/abc/edit_page') + self.assertEqual(info['save_url'], + 'http://example.com/abc/edit_page') def test_it_submitted(self): from tutorial.models import Page diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index fc85d4585..375f1f5a5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -1,20 +1,36 @@ import re - from docutils.core import publish_parts -from pyramid.httpexceptions import HTTPFound, HTTPNotFound -from pyramid.security import authenticated_userid +from pyramid.httpexceptions import ( + HTTPFound, + HTTPNotFound, + HTTPForbidden, + ) + +from pyramid.view import view_config + +from pyramid.security import ( + remember, + forget, + authenticated_userid, + ) -from tutorial.models import DBSession -from tutorial.models import Page +from .models import ( + DBSession, + Page, + ) + +from .security import USERS # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") +@view_config(route_name='view_wiki') def view_wiki(request): return HTTPFound(location = request.route_url('view_page', pagename='FrontPage')) +@view_config(route_name='view_page', renderer='templates/view.pt') def view_page(request): pagename = request.matchdict['pagename'] session = DBSession() @@ -35,10 +51,11 @@ def view_page(request): content = publish_parts(page.data, writer_name='html')['html_body'] content = wikiwords.sub(check, content) edit_url = request.route_url('edit_page', pagename=pagename) - logged_in = authenticated_userid(request) return dict(page=page, content=content, edit_url=edit_url, - logged_in=logged_in) + logged_in=authenticated_userid(request)) +@view_config(route_name='add_page', renderer='templates/edit.pt', + permission='edit') def add_page(request): name = request.matchdict['pagename'] if 'form.submitted' in request.params: @@ -50,9 +67,11 @@ def add_page(request): pagename=name)) save_url = request.route_url('add_page', pagename=name) page = Page('', '') - logged_in = authenticated_userid(request) - return dict(page=page, save_url=save_url, logged_in=logged_in) + return dict(page=page, save_url=save_url, + logged_in=authenticated_userid(request)) +@view_config(route_name='edit_page', renderer='templates/edit.pt', + permission='edit') def edit_page(request): name = request.matchdict['pagename'] session = DBSession() @@ -62,10 +81,43 @@ def edit_page(request): session.add(page) return HTTPFound(location = request.route_url('view_page', pagename=name)) - - logged_in = authenticated_userid(request) return dict( page=page, save_url = request.route_url('edit_page', pagename=name), - logged_in = logged_in, + logged_in=authenticated_userid(request), ) + +@view_config(route_name='login', renderer='templates/login.pt') +@view_config(context=HTTPForbidden, renderer='templates/login.pt') +def login(request): + login_url = request.route_url('login') + referrer = request.url + if referrer == login_url: + referrer = '/' # never use the login form itself as came_from + came_from = request.params.get('came_from', referrer) + message = '' + login = '' + password = '' + if 'form.submitted' in request.params: + login = request.params['login'] + password = request.params['password'] + if USERS.get(login) == password: + headers = remember(request, login) + return HTTPFound(location = came_from, + headers = headers) + message = 'Failed login' + + return dict( + message = message, + url = request.application_url + '/login', + came_from = came_from, + login = login, + password = password, + ) + +@view_config(route_name='logout') +def logout(request): + headers = forget(request) + return HTTPFound(location = request.route_url('view_wiki'), + headers = headers) + -- cgit v1.2.3 From 030d10697cc52a5c26d19818140616a485f63428 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 2 Jan 2012 20:41:44 -0500 Subject: - Use the ``waitress`` WSGI server instead of ``wsgiref`` in scaffolding. --- docs/tutorials/wiki2/src/authorization/development.ini | 2 +- docs/tutorials/wiki2/src/authorization/production.ini | 2 +- docs/tutorials/wiki2/src/authorization/setup.py | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 4f7493cba..2bb74454c 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -13,7 +13,7 @@ pyramid.includes = pyramid_debugtoolbar sqlalchemy.url = sqlite:///%(here)s/tutorial.db [server:main] -use = egg:pyramid#wsgiref +use = egg:waitress#main host = 0.0.0.0 port = 6543 diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 53eaf20a1..ec6dea135 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -12,7 +12,7 @@ pyramid.includes = pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db [server:main] -use = egg:pyramid#wsgiref +use = egg:waitress#main host = 0.0.0.0 port = 6543 diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 09769bfff..7f1ae10b1 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -15,6 +15,7 @@ requires = [ 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'docutils', + 'waitress', ] if sys.version_info[:3] < (2,5,0): -- cgit v1.2.3 From 4ded431cba6729e5f2ac1879df735905006555ac Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 4 Jan 2012 19:02:04 -0500 Subject: remove dependency on pysqlite from all scaffolding on platforms lt 2.6 --- docs/tutorials/wiki2/src/authorization/setup.py | 4 ---- 1 file changed, 4 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 7f1ae10b1..964e39010 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -1,5 +1,4 @@ import os -import sys from setuptools import setup, find_packages @@ -18,9 +17,6 @@ requires = [ 'waitress', ] -if sys.version_info[:3] < (2,5,0): - requires.append('pysqlite') - setup(name='tutorial', version='0.0', description='tutorial', -- cgit v1.2.3 From 9619d0f8b0b4d4aca0e9f68ba1890de2b2860396 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 19 Jan 2012 04:10:51 -0500 Subject: use method-based setting of authorization and authentication policy (see issue #398) --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 04dd5fe82..7e290a1e1 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -17,9 +17,9 @@ def main(global_config, **settings): 'sosecret', callback=groupfinder) authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, - root_factory='tutorial.models.RootFactory', - authentication_policy=authn_policy, - authorization_policy=authz_policy) + root_factory='tutorial.models.RootFactory') + config.set_authentication_policy(authn_policy) + config.set_authorization_policy(authz_policy) config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') -- cgit v1.2.3 From c6a299ad7159ffcabe201fa79f485c388d837971 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 14 Feb 2012 05:57:06 -0500 Subject: - Don't create a ``session`` instance in SQLA Wiki tutorial, use raw ``DBSession`` instead (this is more common in real SQLA apps). --- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index 375f1f5a5..087e6076b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -33,14 +33,13 @@ def view_wiki(request): @view_config(route_name='view_page', renderer='templates/view.pt') def view_page(request): pagename = request.matchdict['pagename'] - session = DBSession() - page = session.query(Page).filter_by(name=pagename).first() + page = DBSession.query(Page).filter_by(name=pagename).first() if page is None: return HTTPNotFound('No such page') def check(match): word = match.group(1) - exists = session.query(Page).filter_by(name=word).all() + exists = DBSession.query(Page).filter_by(name=word).all() if exists: view_url = request.route_url('view_page', pagename=word) return '%s' % (view_url, word) @@ -59,10 +58,9 @@ def view_page(request): def add_page(request): name = request.matchdict['pagename'] if 'form.submitted' in request.params: - session = DBSession() body = request.params['body'] page = Page(name, body) - session.add(page) + DBSession.add(page) return HTTPFound(location = request.route_url('view_page', pagename=name)) save_url = request.route_url('add_page', pagename=name) @@ -74,11 +72,10 @@ def add_page(request): permission='edit') def edit_page(request): name = request.matchdict['pagename'] - session = DBSession() - page = session.query(Page).filter_by(name=name).one() + page = DBSession.query(Page).filter_by(name=name).one() if 'form.submitted' in request.params: page.data = request.params['body'] - session.add(page) + DBSession.add(page) return HTTPFound(location = request.route_url('view_page', pagename=name)) return dict( -- cgit v1.2.3 From d21ba4b61e901b27ceae36f29dac23387a8129d5 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 19 Feb 2012 11:05:33 -0500 Subject: - Put ``pyramid.includes`` targets within ini files in scaffolds on separate lines in order to be able to tell people to comment out only the ``pyramid_debugtoolbar`` line when they want to disable the toolbar. --- docs/tutorials/wiki2/src/authorization/development.ini | 5 +++-- docs/tutorials/wiki2/src/authorization/production.ini | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 2bb74454c..06c51fb12 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -7,8 +7,9 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = true pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - pyramid_tm +pyramid.includes = + pyramid_debugtoolbar + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index ec6dea135..cefb5c231 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -7,7 +7,8 @@ pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.debug_templates = false pyramid.default_locale_name = en -pyramid.includes = pyramid_tm +pyramid.includes = + pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.db -- cgit v1.2.3 From a7fe30f0eabd6c6fd3bcc910faa41720a75056de Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 22 Feb 2012 19:24:09 -0500 Subject: - New API: ``pyramid.config.Configurator.add_forbidden_view``. This is a wrapper for ``pyramid.Config.configurator.add_view`` which does the right thing about permissions. It should be preferred over calling ``add_view`` directly with ``context=HTTPForbidden`` as was previously recommended. - New API: ``pyramid.view.forbidden_view_config``. This is a decorator constructor like ``pyramid.view.view_config`` that calls ``pyramid.config.Configurator.add_forbidden_view`` when scanned. It should be preferred over using ``pyramid.view.view_config`` with ``context=HTTPForbidden`` as was previously recommended. - Updated the "Creating a Not Forbidden View" section of the "Hooks" chapter, replacing explanations of registering a view using ``add_view`` or ``view_config`` with ones using ``add_forbidden_view`` or ``forbidden_view_config``. - Updated all tutorials to use ``pyramid.view.forbidden_view_config`` rather than ``pyramid.view.view_config`` with an HTTPForbidden context. --- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index 087e6076b..1453cd2e6 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -4,10 +4,12 @@ from docutils.core import publish_parts from pyramid.httpexceptions import ( HTTPFound, HTTPNotFound, - HTTPForbidden, ) -from pyramid.view import view_config +from pyramid.view import ( + view_config, + forbidden_view_config, + ) from pyramid.security import ( remember, @@ -85,7 +87,7 @@ def edit_page(request): ) @view_config(route_name='login', renderer='templates/login.pt') -@view_config(context=HTTPForbidden, renderer='templates/login.pt') +@forbidden_view_config(renderer='templates/login.pt') def login(request): login_url = request.route_url('login') referrer = request.url -- cgit v1.2.3 From 58df8cb0697a00f88da347db8c09f7c0148f99c0 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Wed, 14 Mar 2012 13:58:17 -0700 Subject: Removed populate tests from the SQL wiki tutorial - Removed the main() settings parameter in populate.py - Updated the Tests chapter --- docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py index 981adff38..03188e8ad 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py @@ -21,7 +21,7 @@ def usage(argv): '(example: "%s development.ini")' % (cmd, cmd)) sys.exit(1) -def main(argv=sys.argv, settings=None): +def main(argv=sys.argv): if len(argv) != 2: usage(argv) config_uri = argv[1] -- cgit v1.2.3 From c884eea0abeac00fdff6821329c2981caa5c8db4 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Wed, 14 Mar 2012 14:58:05 -0700 Subject: Renamed db populate to initialize in SQL tutorial - Replaced populate_tutorial -> initialize_tutorial_db - Renamed populate.py -> initializedb.py - Updated references in the documenation --- docs/tutorials/wiki2/src/authorization/setup.py | 2 +- .../authorization/tutorial/scripts/initializedb.py | 35 ++++++++++++++++++++++ .../src/authorization/tutorial/scripts/populate.py | 35 ---------------------- 3 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 964e39010..2fd051927 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -40,6 +40,6 @@ setup(name='tutorial', [paste.app_factory] main = tutorial:main [console_scripts] - populate_tutorial = tutorial.scripts.populate:main + initialize_tutorial_db = tutorial.scripts.initializedb:main """, ) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py new file mode 100644 index 000000000..03188e8ad --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py @@ -0,0 +1,35 @@ +import os +import sys +import transaction + +from sqlalchemy import engine_from_config + +from pyramid.paster import ( + get_appsettings, + setup_logging, + ) + +from ..models import ( + DBSession, + Page, + Base, + ) + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \n' + '(example: "%s development.ini")' % (cmd, cmd)) + sys.exit(1) + +def main(argv=sys.argv): + if len(argv) != 2: + usage(argv) + config_uri = argv[1] + setup_logging(config_uri) + settings = get_appsettings(config_uri) + engine = engine_from_config(settings, 'sqlalchemy.') + DBSession.configure(bind=engine) + Base.metadata.create_all(engine) + with transaction.manager: + model = Page('FrontPage', 'This is the front page') + DBSession.add(model) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py deleted file mode 100644 index 03188e8ad..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/populate.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -import sys -import transaction - -from sqlalchemy import engine_from_config - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from ..models import ( - DBSession, - Page, - Base, - ) - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s \n' - '(example: "%s development.ini")' % (cmd, cmd)) - sys.exit(1) - -def main(argv=sys.argv): - if len(argv) != 2: - usage(argv) - config_uri = argv[1] - setup_logging(config_uri) - settings = get_appsettings(config_uri) - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.create_all(engine) - with transaction.manager: - model = Page('FrontPage', 'This is the front page') - DBSession.add(model) -- cgit v1.2.3 From 343fb59c318e35c656611b58e7fe870373e33452 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 17 Mar 2012 14:48:01 -0400 Subject: - Remove references to do-nothing ``pyramid.debug_templates`` setting in all Pyramid-provided ``.ini`` files. This setting previously told Chameleon to render better exceptions; now Chameleon always renders nice exceptions regardless of the value of this setting. Fixes #491. --- docs/tutorials/wiki2/src/authorization/development.ini | 1 - docs/tutorials/wiki2/src/authorization/production.ini | 1 - 2 files changed, 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 06c51fb12..38738f3c6 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -5,7 +5,6 @@ pyramid.reload_templates = true pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false -pyramid.debug_templates = true pyramid.default_locale_name = en pyramid.includes = pyramid_debugtoolbar diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index cefb5c231..c4034abad 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -5,7 +5,6 @@ pyramid.reload_templates = false pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false -pyramid.debug_templates = false pyramid.default_locale_name = en pyramid.includes = pyramid_tm -- cgit v1.2.3 From 4e3de46840501d20472e5e54510ed598906c0b21 Mon Sep 17 00:00:00 2001 From: Toni Mueller Date: Tue, 20 Mar 2012 14:46:49 +0100 Subject: generate more common filenames for sqlite and patch the wiki2 tutorial, too --- docs/tutorials/wiki2/src/authorization/development.ini | 2 +- docs/tutorials/wiki2/src/authorization/production.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 38738f3c6..eb2f878c5 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -10,7 +10,7 @@ pyramid.includes = pyramid_debugtoolbar pyramid_tm -sqlalchemy.url = sqlite:///%(here)s/tutorial.db +sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index c4034abad..4684d2f7a 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -9,7 +9,7 @@ pyramid.default_locale_name = en pyramid.includes = pyramid_tm -sqlalchemy.url = sqlite:///%(here)s/tutorial.db +sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -- cgit v1.2.3 From c226b1ae080aa7d19c47626b07fe6d8ef6bbba9e Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Sun, 8 Apr 2012 07:34:21 -0500 Subject: Normalize Authorization in both tutorials 3 - Sync content in Adding Authentication and Authorization policies, Add permission declarations sections - Added mising permission=view in SQL tutorial - Moved __init__.py listing to Seeing our changes --- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index 1453cd2e6..c7670b049 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -27,12 +27,14 @@ from .security import USERS # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") -@view_config(route_name='view_wiki') +@view_config(route_name='view_wiki', + permission='view') def view_wiki(request): return HTTPFound(location = request.route_url('view_page', pagename='FrontPage')) -@view_config(route_name='view_page', renderer='templates/view.pt') +@view_config(route_name='view_page', renderer='templates/view.pt', + permission='view') def view_page(request): pagename = request.matchdict['pagename'] page = DBSession.query(Page).filter_by(name=pagename).first() -- cgit v1.2.3 From cabcd3788beceb9a41eca2414068ab32aaf3340e Mon Sep 17 00:00:00 2001 From: David Gay Date: Sun, 29 Jul 2012 19:05:07 -0400 Subject: prettify CSS stored in docs tutorials --- .../src/authorization/tutorial/static/pylons.css | 435 ++++++++++++++++++--- 1 file changed, 371 insertions(+), 64 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css index c54499ddd..4b1c017cd 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css @@ -1,65 +1,372 @@ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ -vertical-align:baseline;background:transparent;} -body{line-height:1;} -ol,ul{list-style:none;} -blockquote,q{quotes:none;} -blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -:focus{outline:0;} -ins{text-decoration:none;} -del{text-decoration:line-through;} -table{border-collapse:collapse;border-spacing:0;} -sub{vertical-align:sub;font-size:smaller;line-height:normal;} -sup{vertical-align:super;font-size:smaller;line-height:normal;} -ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} -ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} -li{display:list-item;} -ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} -.hidden{display:none;} -p{line-height:1.5em;} -h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} -h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} -html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;} -a{color:#1b61d6;text-decoration:none;} -a:hover{color:#e88f00;text-decoration:underline;} -body h1, -body h2, -body h3, -body h4, -body h5, -body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} -#wrap{min-height:100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} -#header{background:#000000;top:0;font-size:14px;} -#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} -.header,.footer{width:750px;margin-right:auto;margin-left:auto;} -.wrapper{width:100%} -#top,#top-small,#bottom{width:100%;} -#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} -#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} -#bottom{color:#222;background-color:#ffffff;} -.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} -.top{padding-top:40px;} -.top-small{padding-top:10px;} -#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} -.app-welcome{margin-top:25px;} -.app-name{color:#000000;font-weight:bold;} -.bottom{padding-top:50px;} -#left{width:350px;float:left;padding-right:25px;} -#right{width:350px;float:right;padding-left:25px;} -.align-left{text-align:left;} -.align-right{text-align:right;} -.align-center{text-align:center;} -ul.links{margin:0;padding:0;} -ul.links li{list-style-type:none;font-size:14px;} -form{border-style:none;} -fieldset{border-style:none;} -input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text],input[type=password]{width:205px;} -input[type=submit]{background-color:#ddd;font-weight:bold;} +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td +{ + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; /* 16px */ + vertical-align: baseline; + background: transparent; +} + +body +{ + line-height: 1; +} + +ol, ul +{ + list-style: none; +} + +blockquote, q +{ + quotes: none; +} + +blockquote:before, blockquote:after, q:before, q:after +{ + content: ''; + content: none; +} + +:focus +{ + outline: 0; +} + +ins +{ + text-decoration: none; +} + +del +{ + text-decoration: line-through; +} + +table +{ + border-collapse: collapse; + border-spacing: 0; +} + +sub +{ + vertical-align: sub; + font-size: smaller; + line-height: normal; +} + +sup +{ + vertical-align: super; + font-size: smaller; + line-height: normal; +} + +ul, menu, dir +{ + display: block; + list-style-type: disc; + margin: 1em 0; + padding-left: 40px; +} + +ol +{ + display: block; + list-style-type: decimal-leading-zero; + margin: 1em 0; + padding-left: 40px; +} + +li +{ + display: list-item; +} + +ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl +{ + margin-top: 0; + margin-bottom: 0; +} + +ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir +{ + list-style-type: circle; +} + +ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir +{ + list-style-type: square; +} + +.hidden +{ + display: none; +} + +p +{ + line-height: 1.5em; +} + +h1 +{ + font-size: 1.75em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h2 +{ + font-size: 1.5em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h3 +{ + font-size: 1.25em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +h4 +{ + font-size: 1em; + line-height: 1.7em; + font-family: helvetica, verdana; +} + +html, body +{ + width: 100%; + height: 100%; +} + +body +{ + margin: 0; + padding: 0; + background-color: #fff; + position: relative; + font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; +} + +a +{ + color: #1b61d6; + text-decoration: none; +} + +a:hover +{ + color: #e88f00; + text-decoration: underline; +} + +body h1, body h2, body h3, body h4, body h5, body h6 +{ + font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; + font-weight: 400; + color: #373839; + font-style: normal; +} + +#wrap +{ + min-height: 100%; +} + +#header, #footer +{ + width: 100%; + color: #fff; + height: 40px; + position: absolute; + text-align: center; + line-height: 40px; + overflow: hidden; + font-size: 12px; + vertical-align: middle; +} + +#header +{ + background: #000; + top: 0; + font-size: 14px; +} + +#footer +{ + bottom: 0; + background: #000 url(footerbg.png) repeat-x 0 top; + position: relative; + margin-top: -40px; + clear: both; +} + +.header, .footer +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.wrapper +{ + width: 100%; +} + +#top, #top-small, #bottom +{ + width: 100%; +} + +#top +{ + color: #000; + height: 230px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#top-small +{ + color: #000; + height: 60px; + background: #fff url(headerbg.png) repeat-x 0 top; + position: relative; +} + +#bottom +{ + color: #222; + background-color: #fff; +} + +.top, .top-small, .middle, .bottom +{ + width: 750px; + margin-right: auto; + margin-left: auto; +} + +.top +{ + padding-top: 40px; +} + +.top-small +{ + padding-top: 10px; +} + +#middle +{ + width: 100%; + height: 100px; + background: url(middlebg.png) repeat-x; + border-top: 2px solid #fff; + border-bottom: 2px solid #b2b2b2; +} + +.app-welcome +{ + margin-top: 25px; +} + +.app-name +{ + color: #000; + font-weight: 700; +} + +.bottom +{ + padding-top: 50px; +} + +#left +{ + width: 350px; + float: left; + padding-right: 25px; +} + +#right +{ + width: 350px; + float: right; + padding-left: 25px; +} + +.align-left +{ + text-align: left; +} + +.align-right +{ + text-align: right; +} + +.align-center +{ + text-align: center; +} + +ul.links +{ + margin: 0; + padding: 0; +} + +ul.links li +{ + list-style-type: none; + font-size: 14px; +} + +form +{ + border-style: none; +} + +fieldset +{ + border-style: none; +} + +input +{ + color: #222; + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 12px; + line-height: 16px; +} + +input[type=text], input[type=password] +{ + width: 205px; +} + +input[type=submit] +{ + background-color: #ddd; + font-weight: 700; +} + /*Opera Fix*/ -body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} +body:before +{ + content: ""; + height: 100%; + float: left; + width: 0; + margin-top: -32767px; +} -- cgit v1.2.3 From 4eedc27895e6ef520d313bae255cb56f20380661 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Mon, 10 Sep 2012 21:50:14 -0500 Subject: change variable name ``name`` to ``pagename`` - In the authorization and tests stages --- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index c7670b049..0d085b0e2 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -60,14 +60,14 @@ def view_page(request): @view_config(route_name='add_page', renderer='templates/edit.pt', permission='edit') def add_page(request): - name = request.matchdict['pagename'] + pagename = request.matchdict['pagename'] if 'form.submitted' in request.params: body = request.params['body'] - page = Page(name, body) + page = Page(pagename, body) DBSession.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) - save_url = request.route_url('add_page', pagename=name) + pagename=pagename)) + save_url = request.route_url('add_page', pagename=pagename) page = Page('', '') return dict(page=page, save_url=save_url, logged_in=authenticated_userid(request)) @@ -75,16 +75,16 @@ def add_page(request): @view_config(route_name='edit_page', renderer='templates/edit.pt', permission='edit') def edit_page(request): - name = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=name).one() + pagename = request.matchdict['pagename'] + page = DBSession.query(Page).filter_by(name=pagename).one() if 'form.submitted' in request.params: page.data = request.params['body'] DBSession.add(page) return HTTPFound(location = request.route_url('view_page', - pagename=name)) + pagename=pagename)) return dict( page=page, - save_url = request.route_url('edit_page', pagename=name), + save_url = request.route_url('edit_page', pagename=pagename), logged_in=authenticated_userid(request), ) -- cgit v1.2.3 From 098599b497fb6cd7c9372ceb795e9e8a416d573e Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 22 Sep 2012 10:04:14 -0400 Subject: - Add ``Base.metadata.bind = engine`` to alchemy template, so that tables defined imperatively will work. - update wiki2 SQLA tutorial with the changes required after inserting ``Base.metadata.bind = engine`` into the alchemy scaffold. --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 7e290a1e1..8922a3cc0 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -6,13 +6,17 @@ from sqlalchemy import engine_from_config from tutorial.security import groupfinder -from .models import DBSession +from .models import ( + DBSession, + Base, + ) def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) + Base.metadata.bind = engine authn_policy = AuthTktAuthenticationPolicy( 'sosecret', callback=groupfinder) authz_policy = ACLAuthorizationPolicy() -- cgit v1.2.3 From 04875452db1da40bd8ed0841869d511b8d86527d Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 4 Nov 2012 01:51:42 -0500 Subject: fix docs, upgrade tutorials, add change note, deprecate using zope.deprecation instead of a warning, make hashalg arg a kwarg in certain cases in case someone (maybe me) is using nonapi function imports from authentication --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 8922a3cc0..585cdf884 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -1,5 +1,5 @@ from pyramid.config import Configurator -from pyramid.authentication import AuthTktAuthenticationPolicy +from pyramid.authentication import SHA512AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy from sqlalchemy import engine_from_config @@ -17,7 +17,7 @@ def main(global_config, **settings): engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine - authn_policy = AuthTktAuthenticationPolicy( + authn_policy = SHA512AuthTktAuthenticationPolicy( 'sosecret', callback=groupfinder) authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, -- cgit v1.2.3 From 19b8207ff1e959669d296407ed112545364a495d Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 4 Nov 2012 11:19:41 -0600 Subject: merged SHA512AuthTktAuthenticationPolicy into AuthTktAuthenticationPolicy AuthTktAuthenticationPolicy now accepts a hashalg parameter and is no longer deprecated. Docs recommend overriding hashalg and using 'sha512'. --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 585cdf884..76071173a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -1,5 +1,5 @@ from pyramid.config import Configurator -from pyramid.authentication import SHA512AuthTktAuthenticationPolicy +from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy from sqlalchemy import engine_from_config @@ -17,8 +17,8 @@ def main(global_config, **settings): engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) Base.metadata.bind = engine - authn_policy = SHA512AuthTktAuthenticationPolicy( - 'sosecret', callback=groupfinder) + authn_policy = AuthTktAuthenticationPolicy( + 'sosecret', callback=groupfinder, hashalg='sha512') authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, root_factory='tutorial.models.RootFactory') -- cgit v1.2.3 From c344e532e27ce078643ec3246002d2703ef85416 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Mon, 19 Nov 2012 21:03:46 -0600 Subject: Sync some SQL wiki tutorial files with the scaffold - Files that are not referred to in a literalinclude in the tutorial docs - setup.py appears in literalinclude, but no lines are added or removed so no impact. Fixed docutils order in the requires list. --- docs/tutorials/wiki2/src/authorization/README.txt | 13 +++++++++++++ .../wiki2/src/authorization/development.ini | 20 +++++++++++++++++--- docs/tutorials/wiki2/src/authorization/setup.py | 9 +++++---- 3 files changed, 35 insertions(+), 7 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt index 6f851e9b7..141851285 100644 --- a/docs/tutorials/wiki2/src/authorization/README.txt +++ b/docs/tutorials/wiki2/src/authorization/README.txt @@ -1 +1,14 @@ tutorial README +================== + +Getting Started +--------------- + +- cd + +- $venv/bin/python setup.py develop + +- $venv/bin/initialize_tutorial_db development.ini + +- $venv/bin/pserve development.ini + diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index eb2f878c5..a9d53b296 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -1,3 +1,8 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + [app:main] use = egg:tutorial @@ -12,12 +17,23 @@ pyramid.includes = sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +# By default, the toolbar only appears for clients from IP addresses +# '127.0.0.1' and '::1'. +# debugtoolbar.hosts = 127.0.0.1 ::1 + +### +# wsgi server configuration +### + [server:main] use = egg:waitress#main host = 0.0.0.0 port = 6543 -# Begin logging configuration +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### [loggers] keys = root, tutorial, sqlalchemy @@ -53,5 +69,3 @@ formatter = generic [formatter_generic] format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 2fd051927..d658cae93 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -13,8 +13,8 @@ requires = [ 'pyramid_tm', 'pyramid_debugtoolbar', 'zope.sqlalchemy', - 'docutils', 'waitress', + 'docutils', ] setup(name='tutorial', @@ -23,7 +23,7 @@ setup(name='tutorial', long_description=README + '\n\n' + CHANGES, classifiers=[ "Programming Language :: Python", - "Framework :: Pylons", + "Framework :: Pyramid", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", ], @@ -35,11 +35,12 @@ setup(name='tutorial', include_package_data=True, zip_safe=False, test_suite='tutorial', - install_requires = requires, - entry_points = """\ + install_requires=requires, + entry_points="""\ [paste.app_factory] main = tutorial:main [console_scripts] initialize_tutorial_db = tutorial.scripts.initializedb:main """, ) + -- cgit v1.2.3 From c47b8caa24857c1c35fd0ddf72a237c70b63f5cd Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Sat, 1 Dec 2012 19:23:34 -0600 Subject: Sync setup.py in SQL wiki tutorial --- docs/tutorials/wiki2/src/authorization/setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index d658cae93..36668dd33 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -20,7 +20,7 @@ requires = [ setup(name='tutorial', version='0.0', description='tutorial', - long_description=README + '\n\n' + CHANGES, + long_description=README + '\n\n' + CHANGES, classifiers=[ "Programming Language :: Python", "Framework :: Pyramid", @@ -43,4 +43,3 @@ setup(name='tutorial', initialize_tutorial_db = tutorial.scripts.initializedb:main """, ) - -- cgit v1.2.3 From e90fa43a8051dfc8799596e17b72fd3d3def6516 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Sat, 1 Dec 2012 19:43:02 -0600 Subject: Sync __init__.py in SQL wiki tutorial - Update lines and emphasized-lines - No line numbers if only a single line --- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 76071173a..d08e55bf9 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -11,6 +11,7 @@ from .models import ( Base, ) + def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ @@ -33,4 +34,3 @@ def main(global_config, **settings): config.add_route('edit_page', '/{pagename}/edit_page') config.scan() return config.make_wsgi_app() - -- cgit v1.2.3 From 479178179df2e3554d81d8c42d7ff46b75901c62 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Sat, 1 Dec 2012 22:30:50 -0600 Subject: Sync models.py in SQL wiki tutorial - Update lines and emphasized-lines - No line numbers if only a single line --- docs/tutorials/wiki2/src/authorization/tutorial/models.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py index c3bdcbea5..91e5a0019 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py @@ -21,6 +21,7 @@ from zope.sqlalchemy import ZopeTransactionExtension DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) Base = declarative_base() + class Page(Base): """ The SQLAlchemy declarative model class for a Page object. """ __tablename__ = 'pages' -- cgit v1.2.3 From 412c4b09deb3a53f3c9ee39423b527709ea13097 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Sun, 2 Dec 2012 17:29:20 -0600 Subject: Sync initializedb.py in SQL wiki tutorial --- .../wiki2/src/authorization/tutorial/scripts/initializedb.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py index 03188e8ad..092e359ce 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py @@ -15,12 +15,14 @@ from ..models import ( Base, ) + def usage(argv): cmd = os.path.basename(argv[0]) print('usage: %s \n' - '(example: "%s development.ini")' % (cmd, cmd)) + '(example: "%s development.ini")' % (cmd, cmd)) sys.exit(1) + def main(argv=sys.argv): if len(argv) != 2: usage(argv) -- cgit v1.2.3 From 95a0b80ed0eefae151d00043f85d94534a256b89 Mon Sep 17 00:00:00 2001 From: Patricio Paez Date: Sun, 2 Dec 2012 18:10:33 -0600 Subject: Sync tests.py and views.py in SQL wiki tutorial - No line references to update --- docs/tutorials/wiki2/src/authorization/tutorial/tests.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index 31d2dc6d5..5dcee127b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -1,5 +1,6 @@ import unittest import transaction + from pyramid import testing def _initTestingDB(): -- cgit v1.2.3 From eb3cee262ef52480198fc7f506debe0f35e3554a Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Mon, 4 Mar 2013 22:30:32 +0200 Subject: fix #311 --- docs/tutorials/wiki2/src/authorization/setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 36668dd33..e8fa8f396 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -3,8 +3,10 @@ import os from setuptools import setup, find_packages here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, 'README.txt')).read() -CHANGES = open(os.path.join(here, 'CHANGES.txt')).read() +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() requires = [ 'pyramid', -- cgit v1.2.3 From f73f0e332658fac2583f51247dcd49bd36d63ce4 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Wed, 13 Mar 2013 23:05:17 +0200 Subject: consistency: use $VENV whenever virtualenv binaries are used --- docs/tutorials/wiki2/src/authorization/README.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt index 141851285..68f430110 100644 --- a/docs/tutorials/wiki2/src/authorization/README.txt +++ b/docs/tutorials/wiki2/src/authorization/README.txt @@ -6,9 +6,9 @@ Getting Started - cd -- $venv/bin/python setup.py develop +- $VENV/bin/python setup.py develop -- $venv/bin/initialize_tutorial_db development.ini +- $VENV/bin/initialize_tutorial_db development.ini -- $venv/bin/pserve development.ini +- $VENV/bin/pserve development.ini -- cgit v1.2.3 From 83fefbf3f92183d1d899c8449a03546dd3c022a3 Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Sat, 3 Aug 2013 11:23:20 -0400 Subject: "Web Application Development Framework" -> "Web Framework". Yay. --- .../wiki2/src/authorization/tutorial/templates/mytemplate.pt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt index 14b88d16a..cf3da2073 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt @@ -1,7 +1,7 @@ - The Pyramid Web Application Development Framework + The Pyramid Web Framework @@ -24,7 +24,7 @@

    Welcome to ${project}, an application generated by
    - the Pyramid web application development framework. + the Pyramid Web Framework.

  • -- cgit v1.2.3 From 404b28ba2efb02d93777a3e01fd602c96af8c077 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 6 Sep 2013 00:02:46 -0500 Subject: update the code in the wiki and wiki2 tutorials to use pyramid_chameleon --- docs/tutorials/wiki2/src/authorization/setup.py | 5 +++-- docs/tutorials/wiki2/src/authorization/tutorial/__init__.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index e8fa8f396..09bd63d33 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -10,10 +10,11 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', + 'pyramid_chameleon', + 'pyramid_debugtoolbar', + 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'pyramid_tm', - 'pyramid_debugtoolbar', 'zope.sqlalchemy', 'waitress', 'docutils', diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index d08e55bf9..2ada42171 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -25,6 +25,7 @@ def main(global_config, **settings): root_factory='tutorial.models.RootFactory') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) + config.include('pyramid_chameleon') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') -- cgit v1.2.3 From 4ead1210a1f98faf224f19e9382e1cea6b1dd9f9 Mon Sep 17 00:00:00 2001 From: "sergey.volobuev" Date: Fri, 29 Mar 2013 07:31:42 +1000 Subject: removed __init__ methods from SQLAlchemy models in the documentation because the latter generates a default constructor --- docs/tutorials/wiki2/src/authorization/tutorial/models.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py index 91e5a0019..4f7e1e024 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models.py @@ -29,9 +29,6 @@ class Page(Base): name = Column(Text, unique=True) data = Column(Text) - def __init__(self, name, data): - self.name = name - self.data = data class RootFactory(object): __acl__ = [ (Allow, Everyone, 'view'), -- cgit v1.2.3 From 13cf2dd2c912c1961d429c8a5756622cf960d5bf Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 7 Oct 2013 19:14:49 -0500 Subject: fix some broken positional args to sqlalchemy models --- docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py index 092e359ce..23a5f13f4 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py @@ -33,5 +33,5 @@ def main(argv=sys.argv): DBSession.configure(bind=engine) Base.metadata.create_all(engine) with transaction.manager: - model = Page('FrontPage', 'This is the front page') + model = Page(name='FrontPage', data='This is the front page') DBSession.add(model) -- cgit v1.2.3 From 85aef4a4c0157a59bfd7ea9b3a58b842ac4de0f0 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 8 Oct 2013 19:07:14 -0500 Subject: fix stupid missing named arguments, whyyy --- docs/tutorials/wiki2/src/authorization/tutorial/tests.py | 8 ++++---- docs/tutorials/wiki2/src/authorization/tutorial/views.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index 5dcee127b..9f01d2da5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -14,7 +14,7 @@ def _initTestingDB(): Base.metadata.create_all(engine) DBSession.configure(bind=engine) with transaction.manager: - model = Page('FrontPage', 'This is the front page') + model = Page(name='FrontPage', data='This is the front page') DBSession.add(model) return DBSession @@ -59,7 +59,7 @@ class ViewPageTests(unittest.TestCase): from tutorial.models import Page request = testing.DummyRequest() request.matchdict['pagename'] = 'IDoExist' - page = Page('IDoExist', 'Hello CruelWorld IDoExist') + page = Page(name='IDoExist', data='Hello CruelWorld IDoExist') self.session.add(page) _registerRoutes(self.config) info = self._callFUT(request) @@ -126,7 +126,7 @@ class EditPageTests(unittest.TestCase): _registerRoutes(self.config) request = testing.DummyRequest() request.matchdict = {'pagename':'abc'} - page = Page('abc', 'hello') + page = Page(name='abc', data='hello') self.session.add(page) info = self._callFUT(request) self.assertEqual(info['page'], page) @@ -139,7 +139,7 @@ class EditPageTests(unittest.TestCase): request = testing.DummyRequest({'form.submitted':True, 'body':'Hello yo!'}) request.matchdict = {'pagename':'abc'} - page = Page('abc', 'hello') + page = Page(name='abc', data='hello') self.session.add(page) response = self._callFUT(request) self.assertEqual(response.location, 'http://example.com/abc') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index 0d085b0e2..b6dbbf5f6 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -63,12 +63,12 @@ def add_page(request): pagename = request.matchdict['pagename'] if 'form.submitted' in request.params: body = request.params['body'] - page = Page(pagename, body) + page = Page(name=pagename, data=body) DBSession.add(page) return HTTPFound(location = request.route_url('view_page', pagename=pagename)) save_url = request.route_url('add_page', pagename=pagename) - page = Page('', '') + page = Page(name='', data='') return dict(page=page, save_url=save_url, logged_in=authenticated_userid(request)) -- cgit v1.2.3 From 3657ba974660677050fe4a62441c2073bd71203c Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 30 Oct 2013 20:08:58 -0400 Subject: fix wiki2 tutorial wrt request-method security APIs --- .../wiki2/src/authorization/tutorial/views.py | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index b6dbbf5f6..110d738c2 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -11,12 +11,6 @@ from pyramid.view import ( forbidden_view_config, ) -from pyramid.security import ( - remember, - forget, - authenticated_userid, - ) - from .models import ( DBSession, Page, @@ -55,7 +49,7 @@ def view_page(request): content = wikiwords.sub(check, content) edit_url = request.route_url('edit_page', pagename=pagename) return dict(page=page, content=content, edit_url=edit_url, - logged_in=authenticated_userid(request)) + logged_in=request.authenticated_userid) @view_config(route_name='add_page', renderer='templates/edit.pt', permission='edit') @@ -70,7 +64,7 @@ def add_page(request): save_url = request.route_url('add_page', pagename=pagename) page = Page(name='', data='') return dict(page=page, save_url=save_url, - logged_in=authenticated_userid(request)) + logged_in=request.authenticated_userid) @view_config(route_name='edit_page', renderer='templates/edit.pt', permission='edit') @@ -85,7 +79,7 @@ def edit_page(request): return dict( page=page, save_url = request.route_url('edit_page', pagename=pagename), - logged_in=authenticated_userid(request), + logged_in=request.authenticated_userid, ) @view_config(route_name='login', renderer='templates/login.pt') @@ -103,9 +97,8 @@ def login(request): login = request.params['login'] password = request.params['password'] if USERS.get(login) == password: - headers = remember(request, login) - return HTTPFound(location = came_from, - headers = headers) + request.remember_userid(login) + return HTTPFound(location = came_from) message = 'Failed login' return dict( @@ -118,7 +111,6 @@ def login(request): @view_config(route_name='logout') def logout(request): - headers = forget(request) - return HTTPFound(location = request.route_url('view_wiki'), - headers = headers) + request.forget_userid() + return HTTPFound(location = request.route_url('view_wiki')) -- cgit v1.2.3 From 0dcd56c2c30863c6683c0cf442aa73dfdcd11b13 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 9 Nov 2013 17:11:16 -0500 Subject: undeprecate remember/forget functions and remove remember_userid/forget_userid methods from request --- .../wiki2/src/authorization/tutorial/views.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py index 110d738c2..e954d5a31 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views.py @@ -11,12 +11,18 @@ from pyramid.view import ( forbidden_view_config, ) +from pyramid.security import ( + remember, + forget, + ) + +from .security import USERS + from .models import ( DBSession, Page, ) -from .security import USERS # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") @@ -78,8 +84,8 @@ def edit_page(request): pagename=pagename)) return dict( page=page, - save_url = request.route_url('edit_page', pagename=pagename), - logged_in=request.authenticated_userid, + save_url=request.route_url('edit_page', pagename=pagename), + logged_in=request.authenticated_userid ) @view_config(route_name='login', renderer='templates/login.pt') @@ -97,8 +103,9 @@ def login(request): login = request.params['login'] password = request.params['password'] if USERS.get(login) == password: - request.remember_userid(login) - return HTTPFound(location = came_from) + headers = remember(request, login) + return HTTPFound(location = came_from, + headers = headers) message = 'Failed login' return dict( @@ -111,6 +118,7 @@ def login(request): @view_config(route_name='logout') def logout(request): - request.forget_userid() - return HTTPFound(location = request.route_url('view_wiki')) + headers = forget(request) + return HTTPFound(location = request.route_url('view_wiki'), + headers = headers) -- cgit v1.2.3 From 832c2e8967fa1904fb1a0d3e5d707a11c32aa543 Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 21:49:44 +0200 Subject: Remove Babel from all setup.cfg files --- docs/tutorials/wiki2/src/authorization/setup.cfg | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.cfg b/docs/tutorials/wiki2/src/authorization/setup.cfg index 23b2ad983..807ea6b0e 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.cfg +++ b/docs/tutorials/wiki2/src/authorization/setup.cfg @@ -4,24 +4,3 @@ nocapture=1 cover-package=tutorial with-coverage=1 cover-erase=1 - -[compile_catalog] -directory = tutorial/locale -domain = tutorial -statistics = true - -[extract_messages] -add_comments = TRANSLATORS: -output_file = tutorial/locale/tutorial.pot -width = 80 - -[init_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale - -[update_catalog] -domain = tutorial -input_file = tutorial/locale/tutorial.pot -output_dir = tutorial/locale -previous = true -- cgit v1.2.3 From eab0eb5068754da33123d5a7bc3faf025a3fc14e Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Tue, 8 Apr 2014 22:04:47 +0200 Subject: Drop setup.cfg from scaffolds Since setup.cfg is no longer needed for Babel, and no scaffold or documentation references nose there is no need to keep them. --- docs/tutorials/wiki2/src/authorization/setup.cfg | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/setup.cfg (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.cfg b/docs/tutorials/wiki2/src/authorization/setup.cfg deleted file mode 100644 index 807ea6b0e..000000000 --- a/docs/tutorials/wiki2/src/authorization/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[nosetests] -match=^test -nocapture=1 -cover-package=tutorial -with-coverage=1 -cover-erase=1 -- cgit v1.2.3 From 492f6945b2be2874a97071a93fd786c28515efa6 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 May 2015 00:09:57 -0700 Subject: update templates and static assets for each step --- .../src/authorization/tutorial/static/favicon.ico | Bin 1406 -> 0 bytes .../src/authorization/tutorial/static/footerbg.png | Bin 333 -> 0 bytes .../src/authorization/tutorial/static/headerbg.png | Bin 203 -> 0 bytes .../src/authorization/tutorial/static/ie6.css | 8 - .../src/authorization/tutorial/static/middlebg.png | Bin 2797 -> 0 bytes .../src/authorization/tutorial/static/pylons.css | 372 --------------------- .../tutorial/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../tutorial/static/pyramid-small.png | Bin 7044 -> 0 bytes .../src/authorization/tutorial/static/pyramid.png | Bin 33055 -> 12901 bytes .../src/authorization/tutorial/static/theme.css | 154 +++++++++ .../authorization/tutorial/static/theme.min.css | 1 + .../authorization/tutorial/static/transparent.gif | Bin 49 -> 0 bytes .../src/authorization/tutorial/templates/edit.pt | 124 +++---- .../authorization/tutorial/templates/mytemplate.pt | 130 ++++--- .../src/authorization/tutorial/templates/view.pt | 127 +++---- 15 files changed, 351 insertions(+), 565 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico b/docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/favicon.ico and /dev/null differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png deleted file mode 100644 index 1fbc873da..000000000 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/footerbg.png and /dev/null differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png deleted file mode 100644 index 0596f2020..000000000 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/headerbg.png and /dev/null differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} -#wrap{display:table;height:100%} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png deleted file mode 100644 index 2369cfb7d..000000000 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/middlebg.png and /dev/null differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css deleted file mode 100644 index 4b1c017cd..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/pylons.css +++ /dev/null @@ -1,372 +0,0 @@ -html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td -{ - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; /* 16px */ - vertical-align: baseline; - background: transparent; -} - -body -{ - line-height: 1; -} - -ol, ul -{ - list-style: none; -} - -blockquote, q -{ - quotes: none; -} - -blockquote:before, blockquote:after, q:before, q:after -{ - content: ''; - content: none; -} - -:focus -{ - outline: 0; -} - -ins -{ - text-decoration: none; -} - -del -{ - text-decoration: line-through; -} - -table -{ - border-collapse: collapse; - border-spacing: 0; -} - -sub -{ - vertical-align: sub; - font-size: smaller; - line-height: normal; -} - -sup -{ - vertical-align: super; - font-size: smaller; - line-height: normal; -} - -ul, menu, dir -{ - display: block; - list-style-type: disc; - margin: 1em 0; - padding-left: 40px; -} - -ol -{ - display: block; - list-style-type: decimal-leading-zero; - margin: 1em 0; - padding-left: 40px; -} - -li -{ - display: list-item; -} - -ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl -{ - margin-top: 0; - margin-bottom: 0; -} - -ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir -{ - list-style-type: circle; -} - -ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir -{ - list-style-type: square; -} - -.hidden -{ - display: none; -} - -p -{ - line-height: 1.5em; -} - -h1 -{ - font-size: 1.75em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h2 -{ - font-size: 1.5em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h3 -{ - font-size: 1.25em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -h4 -{ - font-size: 1em; - line-height: 1.7em; - font-family: helvetica, verdana; -} - -html, body -{ - width: 100%; - height: 100%; -} - -body -{ - margin: 0; - padding: 0; - background-color: #fff; - position: relative; - font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif; -} - -a -{ - color: #1b61d6; - text-decoration: none; -} - -a:hover -{ - color: #e88f00; - text-decoration: underline; -} - -body h1, body h2, body h3, body h4, body h5, body h6 -{ - font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif; - font-weight: 400; - color: #373839; - font-style: normal; -} - -#wrap -{ - min-height: 100%; -} - -#header, #footer -{ - width: 100%; - color: #fff; - height: 40px; - position: absolute; - text-align: center; - line-height: 40px; - overflow: hidden; - font-size: 12px; - vertical-align: middle; -} - -#header -{ - background: #000; - top: 0; - font-size: 14px; -} - -#footer -{ - bottom: 0; - background: #000 url(footerbg.png) repeat-x 0 top; - position: relative; - margin-top: -40px; - clear: both; -} - -.header, .footer -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.wrapper -{ - width: 100%; -} - -#top, #top-small, #bottom -{ - width: 100%; -} - -#top -{ - color: #000; - height: 230px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#top-small -{ - color: #000; - height: 60px; - background: #fff url(headerbg.png) repeat-x 0 top; - position: relative; -} - -#bottom -{ - color: #222; - background-color: #fff; -} - -.top, .top-small, .middle, .bottom -{ - width: 750px; - margin-right: auto; - margin-left: auto; -} - -.top -{ - padding-top: 40px; -} - -.top-small -{ - padding-top: 10px; -} - -#middle -{ - width: 100%; - height: 100px; - background: url(middlebg.png) repeat-x; - border-top: 2px solid #fff; - border-bottom: 2px solid #b2b2b2; -} - -.app-welcome -{ - margin-top: 25px; -} - -.app-name -{ - color: #000; - font-weight: 700; -} - -.bottom -{ - padding-top: 50px; -} - -#left -{ - width: 350px; - float: left; - padding-right: 25px; -} - -#right -{ - width: 350px; - float: right; - padding-left: 25px; -} - -.align-left -{ - text-align: left; -} - -.align-right -{ - text-align: right; -} - -.align-center -{ - text-align: center; -} - -ul.links -{ - margin: 0; - padding: 0; -} - -ul.links li -{ - list-style-type: none; - font-size: 14px; -} - -form -{ - border-style: none; -} - -fieldset -{ - border-style: none; -} - -input -{ - color: #222; - border: 1px solid #ccc; - font-family: sans-serif; - font-size: 12px; - line-height: 16px; -} - -input[type=text], input[type=password] -{ - width: 205px; -} - -input[type=submit] -{ - background-color: #ddd; - font-weight: 700; -} - -/*Opera Fix*/ -body:before -{ - content: ""; - height: 100%; - float: left; - width: 0; - margin-top: -32767px; -} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png new file mode 100644 index 000000000..979203112 Binary files /dev/null and b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-16x16.png differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png deleted file mode 100644 index a5bc0ade7..000000000 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid-small.png and /dev/null differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png index 347e05549..4ab837be9 100644 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png and b/docs/tutorials/wiki2/src/authorization/tutorial/static/pyramid.png differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css new file mode 100644 index 000000000..0f4b1a4d4 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.css @@ -0,0 +1,154 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700); +body { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; + color: #ffffff; + background: #bc2131; +} +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: 300; +} +p { + font-weight: 300; +} +.font-normal { + font-weight: 400; +} +.font-semi-bold { + font-weight: 600; +} +.font-bold { + font-weight: 700; +} +.starter-template { + margin-top: 250px; +} +.starter-template .content { + margin-left: 10px; +} +.starter-template .content h1 { + margin-top: 10px; + font-size: 60px; +} +.starter-template .content h1 .smaller { + font-size: 40px; + color: #f2b7bd; +} +.starter-template .content .lead { + font-size: 25px; + color: #f2b7bd; +} +.starter-template .content .lead .font-normal { + color: #ffffff; +} +.starter-template .links { + float: right; + right: 0; + margin-top: 125px; +} +.starter-template .links ul { + display: block; + padding: 0; + margin: 0; +} +.starter-template .links ul li { + list-style: none; + display: inline; + margin: 0 10px; +} +.starter-template .links ul li:first-child { + margin-left: 0; +} +.starter-template .links ul li:last-child { + margin-right: 0; +} +.starter-template .links ul li.current-version { + color: #f2b7bd; + font-weight: 400; +} +.starter-template .links ul li a, a { + color: #f2b7bd; + text-decoration: underline; +} +.starter-template .links ul li a:hover, a:hover { + color: #ffffff; + text-decoration: underline; +} +.starter-template .links ul li .icon-muted { + color: #eb8b95; + margin-right: 5px; +} +.starter-template .links ul li:hover .icon-muted { + color: #ffffff; +} +.starter-template .copyright { + margin-top: 10px; + font-size: 0.9em; + color: #f2b7bd; + text-transform: lowercase; + float: right; + right: 0; +} +@media (max-width: 1199px) { + .starter-template .content h1 { + font-size: 45px; + } + .starter-template .content h1 .smaller { + font-size: 30px; + } + .starter-template .content .lead { + font-size: 20px; + } +} +@media (max-width: 991px) { + .starter-template { + margin-top: 0; + } + .starter-template .logo { + margin: 40px auto; + } + .starter-template .content { + margin-left: 0; + text-align: center; + } + .starter-template .content h1 { + margin-bottom: 20px; + } + .starter-template .links { + float: none; + text-align: center; + margin-top: 60px; + } + .starter-template .copyright { + float: none; + text-align: center; + } +} +@media (max-width: 767px) { + .starter-template .content h1 .smaller { + font-size: 25px; + display: block; + } + .starter-template .content .lead { + font-size: 16px; + } + .starter-template .links { + margin-top: 40px; + } + .starter-template .links ul li { + display: block; + margin: 0; + } + .starter-template .links ul li .icon-muted { + display: none; + } + .starter-template .copyright { + margin-top: 20px; + } +} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css new file mode 100644 index 000000000..2f924bcc5 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css @@ -0,0 +1 @@ +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif b/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif deleted file mode 100644 index 0341802e5..000000000 Binary files a/docs/tutorials/wiki2/src/authorization/tutorial/static/transparent.gif and /dev/null differ diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt index ca28b9fa5..50e55c850 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt @@ -1,62 +1,74 @@ - - - - ${page.name} - Pyramid tutorial wiki (based on +<!DOCTYPE html> +<html lang="${request.locale_name}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="${request.static_url('tutorial:static/pyramid-16x16.png')}"> + + <title>${page.name} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - - - - - - - - -
    -
    -
    -
    - pyramid + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +

    + Editing Page Name Goes + Here +

    +

    You can return to the + FrontPage. +

    +

    + + Logout + +

    +
    +
    + +
    +
    + +
    +
    +
    +
    -
    -
    -
    -
    -
    - Editing Page Name - Goes Here
    - You can return to the - FrontPage.
    -
    -
    -
    -
    -
    - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt index 64e592ea9..331d52d2a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -1,58 +1,74 @@ - - - - Login - Pyramid tutorial wiki (based on TurboGears - 20-Minute Wiki) - - - - - - - - -
    -
    -
    -
    - pyramid + + + + + + + + + + + Login - Pyramid tutorial wiki (based on + TurboGears 20-Minute Wiki) + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +

    + + Login + + +

    + + +
    + + +
    +
    + + +
    +
    + +
    + +
    +
    -
    -
    -
    -
    -
    - Login
    - +
    +
    - -
    -
    -
    -
    -
    - -
    -
    - -
    -
    - - + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt index 4e5772de0..02cb8e73b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt @@ -33,6 +33,9 @@
    +

    + Logout +

    Page text goes here.
    @@ -48,11 +51,6 @@

    You can return to the FrontPage.

    -

    - - Logout - -

    -- cgit v1.2.3 From 5f375c7603c0e240a60b884bf0ef39352c25c879 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 May 2015 02:44:38 -0700 Subject: - clean up and make consistent across both wikis authorization.rst - update templates and static assets to new theme --- docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt index 331d52d2a..4a938e9bb 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt @@ -36,7 +36,7 @@

    Login - +

    -- cgit v1.2.3 From 4040cf7ef5a9843e25db69b3a17b3796f3a39fb8 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 16 Nov 2015 00:17:20 -0800 Subject: - complete rewrite of wiki2/authorization.rst - add wiki2/src/authorization/ files - improve tag in views/tutorial/templates/edit.jinja2 --- .../wiki2/src/authorization/development.ini | 4 +- .../wiki2/src/authorization/production.ini | 14 +- docs/tutorials/wiki2/src/authorization/setup.py | 2 +- .../wiki2/src/authorization/tutorial/__init__.py | 18 +-- .../wiki2/src/authorization/tutorial/models.py | 37 ----- .../src/authorization/tutorial/models/__init__.py | 7 + .../src/authorization/tutorial/models/meta.py | 46 ++++++ .../src/authorization/tutorial/models/mymodel.py | 26 +++ .../authorization/tutorial/scripts/initializedb.py | 25 +-- .../wiki2/src/authorization/tutorial/security.py | 7 - .../authorization/tutorial/security/__init__.py | 1 + .../src/authorization/tutorial/security/default.py | 7 + .../authorization/tutorial/static/theme.min.css | 2 +- .../authorization/tutorial/templates/edit.jinja2 | 73 +++++++++ .../src/authorization/tutorial/templates/edit.pt | 72 --------- .../authorization/tutorial/templates/layout.jinja2 | 66 ++++++++ .../authorization/tutorial/templates/login.jinja2 | 74 +++++++++ .../src/authorization/tutorial/templates/login.pt | 74 --------- .../tutorial/templates/mytemplate.jinja2 | 8 + .../authorization/tutorial/templates/mytemplate.pt | 66 -------- .../authorization/tutorial/templates/view.jinja2 | 71 +++++++++ .../src/authorization/tutorial/templates/view.pt | 72 --------- .../wiki2/src/authorization/tutorial/tests.py | 175 ++++++--------------- .../wiki2/src/authorization/tutorial/views.py | 124 --------------- .../src/authorization/tutorial/views/__init__.py | 0 .../src/authorization/tutorial/views/default.py | 120 ++++++++++++++ 26 files changed, 579 insertions(+), 612 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/security.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/security/default.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views/__init__.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views/default.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index a9d53b296..99c4ff0fe 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -27,7 +27,7 @@ sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite [server:main] use = egg:waitress#main -host = 0.0.0.0 +host = 127.0.0.1 port = 6543 ### @@ -68,4 +68,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 4684d2f7a..97acfbd7d 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -1,3 +1,8 @@ +### +# app configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +### + [app:main] use = egg:tutorial @@ -16,7 +21,10 @@ use = egg:waitress#main host = 0.0.0.0 port = 6543 -# Begin logging configuration +### +# logging configuration +# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +### [loggers] keys = root, tutorial, sqlalchemy @@ -51,6 +59,4 @@ level = NOTSET formatter = generic [formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration +format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 09bd63d33..d4e5a4072 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - 'pyramid_chameleon', + 'pyramid_jinja2', 'pyramid_debugtoolbar', 'pyramid_tm', 'SQLAlchemy', diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 2ada42171..084fee19f 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -2,30 +2,20 @@ from pyramid.config import Configurator from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy -from sqlalchemy import engine_from_config - -from tutorial.security import groupfinder - -from .models import ( - DBSession, - Base, - ) - +from security.default import groupfinder def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) - Base.metadata.bind = engine authn_policy = AuthTktAuthenticationPolicy( 'sosecret', callback=groupfinder, hashalg='sha512') authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings, - root_factory='tutorial.models.RootFactory') + root_factory='tutorial.models.mymodel.RootFactory') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) - config.include('pyramid_chameleon') + config.include('pyramid_jinja2') + config.include('.models.meta') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models.py b/docs/tutorials/wiki2/src/authorization/tutorial/models.py deleted file mode 100644 index 4f7e1e024..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models.py +++ /dev/null @@ -1,37 +0,0 @@ -from pyramid.security import ( - Allow, - Everyone, - ) - -from sqlalchemy import ( - Column, - Integer, - Text, - ) - -from sqlalchemy.ext.declarative import declarative_base - -from sqlalchemy.orm import ( - scoped_session, - sessionmaker, - ) - -from zope.sqlalchemy import ZopeTransactionExtension - -DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) -Base = declarative_base() - - -class Page(Base): - """ The SQLAlchemy declarative model class for a Page object. """ - __tablename__ = 'pages' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - data = Column(Text) - - -class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] - def __init__(self, request): - pass diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py new file mode 100644 index 000000000..7b1c62867 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py @@ -0,0 +1,7 @@ +from sqlalchemy.orm import configure_mappers +# import all models classes here for sqlalchemy mappers +# to pick up +from .mymodel import Page # flake8: noqa + +# run configure mappers to ensure we avoid any race conditions +configure_mappers() diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py new file mode 100644 index 000000000..b72b45f9f --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py @@ -0,0 +1,46 @@ +from sqlalchemy import engine_from_config +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy.schema import MetaData +import zope.sqlalchemy + +NAMING_CONVENTION = { + "ix": 'ix_%(column_0_label)s', + "uq": "uq_%(table_name)s_%(column_0_name)s", + "ck": "ck_%(table_name)s_%(constraint_name)s", + "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + "pk": "pk_%(table_name)s" +} + +metadata = MetaData(naming_convention=NAMING_CONVENTION) +Base = declarative_base(metadata=metadata) + + +def includeme(config): + settings = config.get_settings() + dbmaker = get_dbmaker(get_engine(settings)) + + config.add_request_method( + lambda r: get_session(r.tm, dbmaker), + 'dbsession', + reify=True + ) + + config.include('pyramid_tm') + + +def get_session(transaction_manager, dbmaker): + dbsession = dbmaker() + zope.sqlalchemy.register(dbsession, + transaction_manager=transaction_manager) + return dbsession + + +def get_engine(settings, prefix='sqlalchemy.'): + return engine_from_config(settings, prefix) + + +def get_dbmaker(engine): + dbmaker = sessionmaker() + dbmaker.configure(bind=engine) + return dbmaker diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py new file mode 100644 index 000000000..03e2f90ca --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py @@ -0,0 +1,26 @@ +from .meta import Base + +from pyramid.security import ( + Allow, + Everyone, + ) + +from sqlalchemy import ( + Column, + Integer, + Text, + ) + + +class Page(Base): + """ The SQLAlchemy declarative model class for a Page object. """ + __tablename__ = 'pages' + id = Column(Integer, primary_key=True) + name = Column(Text, unique=True) + data = Column(Integer) + +class RootFactory(object): + __acl__ = [ (Allow, Everyone, 'view'), + (Allow, 'group:editors', 'edit') ] + def __init__(self, request): + pass \ No newline at end of file diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py index 23a5f13f4..4aac4a848 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py @@ -2,36 +2,41 @@ import os import sys import transaction -from sqlalchemy import engine_from_config - from pyramid.paster import ( get_appsettings, setup_logging, ) -from ..models import ( - DBSession, - Page, +from ..models.meta import ( Base, + get_session, + get_engine, + get_dbmaker, ) +from ..models.mymodel import Page def usage(argv): cmd = os.path.basename(argv[0]) - print('usage: %s <config_uri>\n' + print('usage: %s <config_uri> [var=value]\n' '(example: "%s development.ini")' % (cmd, cmd)) sys.exit(1) def main(argv=sys.argv): - if len(argv) != 2: + if len(argv) < 2: usage(argv) config_uri = argv[1] setup_logging(config_uri) settings = get_appsettings(config_uri) - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) + + engine = get_engine(settings) + dbmaker = get_dbmaker(engine) + + dbsession = get_session(transaction.manager, dbmaker) + Base.metadata.create_all(engine) + with transaction.manager: model = Page(name='FrontPage', data='This is the front page') - DBSession.add(model) + dbsession.add(model) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security.py b/docs/tutorials/wiki2/src/authorization/tutorial/security.py deleted file mode 100644 index d88c9c71f..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/security.py +++ /dev/null @@ -1,7 +0,0 @@ -USERS = {'editor':'editor', - 'viewer':'viewer'} -GROUPS = {'editor':['group:editors']} - -def groupfinder(userid, request): - if userid in USERS: - return GROUPS.get(userid, []) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py @@ -0,0 +1 @@ +# package diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py new file mode 100644 index 000000000..d88c9c71f --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py @@ -0,0 +1,7 @@ +USERS = {'editor':'editor', + 'viewer':'viewer'} +GROUPS = {'editor':['group:editors']} + +def groupfinder(userid, request): + if userid in USERS: + return GROUPS.get(userid, []) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css index 2f924bcc5..0d25de5b6 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css +++ b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css @@ -1 +1 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a,a{color:#f2b7bd;text-decoration:underline}.starter-template .links ul li a:hover,a:hover{color:#fff;text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 new file mode 100644 index 000000000..c4f3a2c93 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<html lang="{{request.locale_name}}"> + <head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta name="description" content="pyramid web application"> + <meta name="author" content="Pylons Project"> + <link rel="shortcut icon" href="{{request.static_url('tutorial:static/pyramid-16x16.png')}}"> + + <title>Edit{% if page.name %} {{page.name}}{% endif %} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    + {% if logged_in %} +

    + Logout +

    + {% endif %} +

    + Editing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +

    +

    You can return to the + FrontPage. +

    + +
    + +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt deleted file mode 100644 index ed355434d..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.pt +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - ${page.name} - Pyramid tutorial wiki (based on - TurboGears 20-Minute Wiki) - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    - Logout -

    -

    - Editing Page Name Goes - Here -

    -

    You can return to the - FrontPage. -

    -
    -
    - -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 new file mode 100644 index 000000000..ff624c65b --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 @@ -0,0 +1,66 @@ + + + + + + + + + + + Alchemy Scaffold for The Pyramid Web Framework + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    + {% block content %} +

    No content

    + {% endblock content %} +
    +
    +
    + +
    +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 new file mode 100644 index 000000000..a80a2a165 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 @@ -0,0 +1,74 @@ + + + + + + + + + + + Login - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    +

    + + Login +
    + {{ message }} +

    +
    + +
    + + +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt deleted file mode 100644 index 4a938e9bb..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.pt +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - Login - Pyramid tutorial wiki (based on - TurboGears 20-Minute Wiki) - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    - - Login -
    - -

    -
    - -
    - - -
    -
    - - -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 new file mode 100644 index 000000000..bb622bf5a --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Alchemy scaffold

    +

    Welcome to {{project}}, an application generated by
    the Pyramid Web Framework 1.7.dev0.

    +
    +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt deleted file mode 100644 index c9b0cec21..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - Alchemy Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    Pyramid Alchemy scaffold

    -

    Welcome to ${project}, an application generated by
    the Pyramid Web Framework.

    -
    -
    -
    - -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 new file mode 100644 index 000000000..a7afc66fc --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 @@ -0,0 +1,71 @@ + + + + + + + + + + + {{page.name}} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    + {% if logged_in %} +

    + Logout +

    + {% endif %} +

    {{ content|safe }}

    +

    + + Edit this page + +

    +

    + Viewing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +

    +

    You can return to the + FrontPage. +

    +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt deleted file mode 100644 index 02cb8e73b..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.pt +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - ${page.name} - Pyramid tutorial wiki (based on - TurboGears 20-Minute Wiki) - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    - Logout -

    -
    - Page text goes here. -
    -

    - - Edit this page - -

    -

    - Viewing - Page Name Goes Here -

    -

    You can return to the - FrontPage. -

    -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index 9f01d2da5..b947e3bb1 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -3,144 +3,63 @@ import transaction from pyramid import testing -def _initTestingDB(): - from sqlalchemy import create_engine - from tutorial.models import ( - DBSession, - Page, - Base - ) - engine = create_engine('sqlite://') - Base.metadata.create_all(engine) - DBSession.configure(bind=engine) - with transaction.manager: - model = Page(name='FrontPage', data='This is the front page') - DBSession.add(model) - return DBSession - -def _registerRoutes(config): - config.add_route('view_page', '{pagename}') - config.add_route('edit_page', '{pagename}/edit_page') - config.add_route('add_page', 'add_page/{pagename}') - -class ViewWikiTests(unittest.TestCase): + +def dummy_request(dbsession): + return testing.DummyRequest(dbsession=dbsession) + + +class BaseTest(unittest.TestCase): def setUp(self): - self.config = testing.setUp() - self.session = _initTestingDB() + self.config = testing.setUp(settings={ + 'sqlalchemy.url': 'sqlite:///:memory:' + }) + self.config.include('.models.meta') + settings = self.config.get_settings() - def tearDown(self): - self.session.remove() - testing.tearDown() + from .models.meta import ( + get_session, + get_engine, + get_dbmaker, + ) - def _callFUT(self, request): - from tutorial.views import view_wiki - return view_wiki(request) + self.engine = get_engine(settings) + dbmaker = get_dbmaker(self.engine) - def test_it(self): - _registerRoutes(self.config) - request = testing.DummyRequest() - response = self._callFUT(request) - self.assertEqual(response.location, 'http://example.com/FrontPage') + self.session = get_session(transaction.manager, dbmaker) -class ViewPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() + def init_database(self): + from .models.meta import Base + Base.metadata.create_all(self.engine) def tearDown(self): - self.session.remove() - testing.tearDown() - - def _callFUT(self, request): - from tutorial.views import view_page - return view_page(request) - - def test_it(self): - from tutorial.models import Page - request = testing.DummyRequest() - request.matchdict['pagename'] = 'IDoExist' - page = Page(name='IDoExist', data='Hello CruelWorld IDoExist') - self.session.add(page) - _registerRoutes(self.config) - info = self._callFUT(request) - self.assertEqual(info['page'], page) - self.assertEqual( - info['content'], - '
    \n' - '

    Hello ' - 'CruelWorld ' - '' - 'IDoExist' - '

    \n
    \n') - self.assertEqual(info['edit_url'], - 'http://example.com/IDoExist/edit_page') - - -class AddPageTests(unittest.TestCase): - def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() + from .models.meta import Base - def tearDown(self): - self.session.remove() testing.tearDown() + transaction.abort() + Base.metadata.create_all(self.engine) + + +class TestMyViewSuccessCondition(BaseTest): - def _callFUT(self, request): - from tutorial.views import add_page - return add_page(request) - - def test_it_notsubmitted(self): - _registerRoutes(self.config) - request = testing.DummyRequest() - request.matchdict = {'pagename':'AnotherPage'} - info = self._callFUT(request) - self.assertEqual(info['page'].data,'') - self.assertEqual(info['save_url'], - 'http://example.com/add_page/AnotherPage') - - def test_it_submitted(self): - from tutorial.models import Page - _registerRoutes(self.config) - request = testing.DummyRequest({'form.submitted':True, - 'body':'Hello yo!'}) - request.matchdict = {'pagename':'AnotherPage'} - self._callFUT(request) - page = self.session.query(Page).filter_by(name='AnotherPage').one() - self.assertEqual(page.data, 'Hello yo!') - -class EditPageTests(unittest.TestCase): def setUp(self): - self.session = _initTestingDB() - self.config = testing.setUp() + super(TestMyViewSuccessCondition, self).setUp() + self.init_database() - def tearDown(self): - self.session.remove() - testing.tearDown() + from .models.mymodel import MyModel + + model = MyModel(name='one', value=55) + self.session.add(model) + + def test_passing_view(self): + from .views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info['one'].name, 'one') + self.assertEqual(info['project'], 'tutorial') + + +class TestMyViewFailureCondition(BaseTest): - def _callFUT(self, request): - from tutorial.views import edit_page - return edit_page(request) - - def test_it_notsubmitted(self): - from tutorial.models import Page - _registerRoutes(self.config) - request = testing.DummyRequest() - request.matchdict = {'pagename':'abc'} - page = Page(name='abc', data='hello') - self.session.add(page) - info = self._callFUT(request) - self.assertEqual(info['page'], page) - self.assertEqual(info['save_url'], - 'http://example.com/abc/edit_page') - - def test_it_submitted(self): - from tutorial.models import Page - _registerRoutes(self.config) - request = testing.DummyRequest({'form.submitted':True, - 'body':'Hello yo!'}) - request.matchdict = {'pagename':'abc'} - page = Page(name='abc', data='hello') - self.session.add(page) - response = self._callFUT(request) - self.assertEqual(response.location, 'http://example.com/abc') - self.assertEqual(page.data, 'Hello yo!') + def test_failing_view(self): + from .views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views.py b/docs/tutorials/wiki2/src/authorization/tutorial/views.py deleted file mode 100644 index e954d5a31..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views.py +++ /dev/null @@ -1,124 +0,0 @@ -import re -from docutils.core import publish_parts - -from pyramid.httpexceptions import ( - HTTPFound, - HTTPNotFound, - ) - -from pyramid.view import ( - view_config, - forbidden_view_config, - ) - -from pyramid.security import ( - remember, - forget, - ) - -from .security import USERS - -from .models import ( - DBSession, - Page, - ) - - -# regular expression used to find WikiWords -wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") - -@view_config(route_name='view_wiki', - permission='view') -def view_wiki(request): - return HTTPFound(location = request.route_url('view_page', - pagename='FrontPage')) - -@view_config(route_name='view_page', renderer='templates/view.pt', - permission='view') -def view_page(request): - pagename = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=pagename).first() - if page is None: - return HTTPNotFound('No such page') - - def check(match): - word = match.group(1) - exists = DBSession.query(Page).filter_by(name=word).all() - if exists: - view_url = request.route_url('view_page', pagename=word) - return '%s' % (view_url, word) - else: - add_url = request.route_url('add_page', pagename=word) - return '%s' % (add_url, word) - - content = publish_parts(page.data, writer_name='html')['html_body'] - content = wikiwords.sub(check, content) - edit_url = request.route_url('edit_page', pagename=pagename) - return dict(page=page, content=content, edit_url=edit_url, - logged_in=request.authenticated_userid) - -@view_config(route_name='add_page', renderer='templates/edit.pt', - permission='edit') -def add_page(request): - pagename = request.matchdict['pagename'] - if 'form.submitted' in request.params: - body = request.params['body'] - page = Page(name=pagename, data=body) - DBSession.add(page) - return HTTPFound(location = request.route_url('view_page', - pagename=pagename)) - save_url = request.route_url('add_page', pagename=pagename) - page = Page(name='', data='') - return dict(page=page, save_url=save_url, - logged_in=request.authenticated_userid) - -@view_config(route_name='edit_page', renderer='templates/edit.pt', - permission='edit') -def edit_page(request): - pagename = request.matchdict['pagename'] - page = DBSession.query(Page).filter_by(name=pagename).one() - if 'form.submitted' in request.params: - page.data = request.params['body'] - DBSession.add(page) - return HTTPFound(location = request.route_url('view_page', - pagename=pagename)) - return dict( - page=page, - save_url=request.route_url('edit_page', pagename=pagename), - logged_in=request.authenticated_userid - ) - -@view_config(route_name='login', renderer='templates/login.pt') -@forbidden_view_config(renderer='templates/login.pt') -def login(request): - login_url = request.route_url('login') - referrer = request.url - if referrer == login_url: - referrer = '/' # never use the login form itself as came_from - came_from = request.params.get('came_from', referrer) - message = '' - login = '' - password = '' - if 'form.submitted' in request.params: - login = request.params['login'] - password = request.params['password'] - if USERS.get(login) == password: - headers = remember(request, login) - return HTTPFound(location = came_from, - headers = headers) - message = 'Failed login' - - return dict( - message = message, - url = request.application_url + '/login', - came_from = came_from, - login = login, - password = password, - ) - -@view_config(route_name='logout') -def logout(request): - headers = forget(request) - return HTTPFound(location = request.route_url('view_wiki'), - headers = headers) - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py new file mode 100644 index 000000000..f35f041a4 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -0,0 +1,120 @@ +import cgi +import re +from docutils.core import publish_parts + +from pyramid.httpexceptions import ( + HTTPFound, + HTTPNotFound, + ) + +from pyramid.view import ( + view_config, + forbidden_view_config, + ) + +from pyramid.security import ( + remember, + forget, + ) + +from ..security.default import USERS + +from ..models.mymodel import Page + +# regular expression used to find WikiWords +wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") + +@view_config(route_name='view_wiki', + permission='view') +def view_wiki(request): + return HTTPFound(location=request.route_url('view_page', + pagename='FrontPage')) + +@view_config(route_name='view_page', renderer='templates/view.jinja2', + permission='view') +def view_page(request): + pagename = request.matchdict['pagename'] + page = request.dbsession.query(Page).filter_by(name=pagename).first() + if page is None: + return HTTPNotFound('No such page') + + def check(match): + word = match.group(1) + exists = request.dbsession.query(Page).filter_by(name=word).all() + if exists: + view_url = request.route_url('view_page', pagename=word) + return '%s' % (view_url, cgi.escape(word)) + else: + add_url = request.route_url('add_page', pagename=word) + return '%s' % (add_url, cgi.escape(word)) + + content = publish_parts(page.data, writer_name='html')['html_body'] + content = wikiwords.sub(check, content) + edit_url = request.route_url('edit_page', pagename=pagename) + return dict(page=page, content=content, edit_url=edit_url, + logged_in=request.authenticated_userid) + +@view_config(route_name='add_page', renderer='templates/edit.jinja2', + permission='edit') +def add_page(request): + pagename = request.matchdict['pagename'] + if 'form.submitted' in request.params: + body = request.params['body'] + page = Page(name=pagename, data=body) + request.dbsession.add(page) + return HTTPFound(location = request.route_url('view_page', + pagename=pagename)) + save_url = request.route_url('add_page', pagename=pagename) + page = Page(name='', data='') + return dict(page=page, save_url=save_url, + logged_in=request.authenticated_userid) + +@view_config(route_name='edit_page', renderer='templates/edit.jinja2', + permission='edit') +def edit_page(request): + pagename = request.matchdict['pagename'] + page = request.dbsession.query(Page).filter_by(name=pagename).one() + if 'form.submitted' in request.params: + page.data = request.params['body'] + request.dbsession.add(page) + return HTTPFound(location = request.route_url('view_page', + pagename=pagename)) + return dict( + page=page, + save_url = request.route_url('edit_page', pagename=pagename), + logged_in=request.authenticated_userid + ) + +@view_config(route_name='login', renderer='templates/login.jinja2') +@forbidden_view_config(renderer='templates/login.jinja2') +def login(request): + login_url = request.route_url('login') + referrer = request.url + if referrer == login_url: + referrer = '/' # never use the login form itself as came_from + came_from = request.params.get('came_from', referrer) + message = '' + login = '' + password = '' + if 'form.submitted' in request.params: + login = request.params['login'] + password = request.params['password'] + if USERS.get(login) == password: + headers = remember(request, login) + return HTTPFound(location = came_from, + headers = headers) + message = 'Failed login' + + return dict( + message = message, + url = request.application_url + '/login', + came_from = came_from, + login = login, + password = password, + ) + +@view_config(route_name='logout') +def logout(request): + headers = forget(request) + return HTTPFound(location = request.route_url('view_wiki'), + headers = headers) -- cgit v1.2.3 From 022a6e0f05b72c679aada6b3c9313c4fd5b31b80 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 2 Dec 2015 04:30:47 -0800 Subject: - add comment to NAMING_CONVENTION per 9b12c01168cb756ec36351d7414cad95e87f6581 --- docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py index b72b45f9f..80ececd8c 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py @@ -4,6 +4,9 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy.schema import MetaData import zope.sqlalchemy +# Recommended naming convention used by Alembic, as various different database +# providers will autogenerate vastly different names making migrations more +# difficult. See: http://alembic.readthedocs.org/en/latest/naming.html NAMING_CONVENTION = { "ix": 'ix_%(column_0_label)s', "uq": "uq_%(table_name)s_%(column_0_name)s", -- cgit v1.2.3 From 14cff75aca9c2858d0575d8e6beba9758eb012d6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 7 Feb 2016 23:39:33 -0600 Subject: update authorization chapter of wiki2 tutorial --- docs/tutorials/wiki2/src/authorization/MANIFEST.in | 2 +- .../wiki2/src/authorization/production.ini | 2 - .../wiki2/src/authorization/tutorial/__init__.py | 11 ++-- .../src/authorization/tutorial/models/__init__.py | 71 +++++++++++++++++++++- .../src/authorization/tutorial/models/meta.py | 33 ---------- .../src/authorization/tutorial/models/mymodel.py | 19 +++--- .../authorization/tutorial/scripts/initializedb.py | 27 ++++---- .../authorization/tutorial/security/__init__.py | 1 - .../src/authorization/tutorial/security/default.py | 11 +++- .../authorization/tutorial/templates/404.jinja2 | 8 +++ .../authorization/tutorial/templates/edit.jinja2 | 6 +- .../authorization/tutorial/templates/view.jinja2 | 6 +- .../wiki2/src/authorization/tutorial/tests.py | 18 +++--- .../src/authorization/tutorial/views/default.py | 54 +++++++--------- .../src/authorization/tutorial/views/errors.py | 5 ++ 15 files changed, 160 insertions(+), 114 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/MANIFEST.in b/docs/tutorials/wiki2/src/authorization/MANIFEST.in index 81beba1b1..42cd299b5 100644 --- a/docs/tutorials/wiki2/src/authorization/MANIFEST.in +++ b/docs/tutorials/wiki2/src/authorization/MANIFEST.in @@ -1,2 +1,2 @@ include *.txt *.ini *.cfg *.rst -recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml +recursive-include tutorial *.ico *.png *.css *.gif *.jpg *.jinja2 *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 97acfbd7d..cb1db3211 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -11,8 +11,6 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = - pyramid_tm sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 084fee19f..a62c42378 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -2,7 +2,8 @@ from pyramid.config import Configurator from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy -from security.default import groupfinder +from .security.default import groupfinder + def main(global_config, **settings): """ This function returns a Pyramid WSGI application. @@ -10,12 +11,12 @@ def main(global_config, **settings): authn_policy = AuthTktAuthenticationPolicy( 'sosecret', callback=groupfinder, hashalg='sha512') authz_policy = ACLAuthorizationPolicy() - config = Configurator(settings=settings, - root_factory='tutorial.models.mymodel.RootFactory') + config = Configurator(settings=settings) + config.include('pyramid_jinja2') + config.include('.models') + config.set_root_factory('.models.mymodel.RootFactory') config.set_authentication_policy(authn_policy) config.set_authorization_policy(authz_policy) - config.include('pyramid_jinja2') - config.include('.models.meta') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py index 7b1c62867..4810c357a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py @@ -1,7 +1,72 @@ +from sqlalchemy import engine_from_config +from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import configure_mappers -# import all models classes here for sqlalchemy mappers -# to pick up +import zope.sqlalchemy + +# import or define all models here to ensure they are attached to the +# Base.metadata prior to any initialization routines from .mymodel import Page # flake8: noqa -# run configure mappers to ensure we avoid any race conditions +# run configure_mappers after defining all of the models to ensure +# all relationships can be setup configure_mappers() + + +def get_engine(settings, prefix='sqlalchemy.'): + return engine_from_config(settings, prefix) + + +def get_session_factory(engine): + factory = sessionmaker() + factory.configure(bind=engine) + return factory + + +def get_tm_session(session_factory, transaction_manager): + """ + Get a ``sqlalchemy.orm.Session`` instance backed by a transaction. + + This function will hook the session to the transaction manager which + will take care of committing any changes. + + - When using pyramid_tm it will automatically be committed or aborted + depending on whether an exception is raised. + + - When using scripts you should wrap the session in a manager yourself. + For example:: + + import transaction + + engine = get_engine(settings) + session_factory = get_session_factory(engine) + with transaction.manager: + dbsession = get_tm_session(session_factory, transaction.manager) + + """ + dbsession = session_factory() + zope.sqlalchemy.register( + dbsession, transaction_manager=transaction_manager) + return dbsession + + +def includeme(config): + """ + Initialize the model for a Pyramid app. + + Activate this setup using ``config.include('tutorial.models')``. + + """ + settings = config.get_settings() + + # use pyramid_tm to hook the transaction lifecycle to the request + config.include('pyramid_tm') + + session_factory = get_session_factory(get_engine(settings)) + + # make request.dbsession available for use in Pyramid + config.add_request_method( + # r.tm is the transaction manager used by pyramid_tm + lambda r: get_tm_session(session_factory, r.tm), + 'dbsession', + reify=True + ) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py index 80ececd8c..fc3e8f1dd 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/meta.py @@ -1,8 +1,5 @@ -from sqlalchemy import engine_from_config from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.orm import sessionmaker from sqlalchemy.schema import MetaData -import zope.sqlalchemy # Recommended naming convention used by Alembic, as various different database # providers will autogenerate vastly different names making migrations more @@ -17,33 +14,3 @@ NAMING_CONVENTION = { metadata = MetaData(naming_convention=NAMING_CONVENTION) Base = declarative_base(metadata=metadata) - - -def includeme(config): - settings = config.get_settings() - dbmaker = get_dbmaker(get_engine(settings)) - - config.add_request_method( - lambda r: get_session(r.tm, dbmaker), - 'dbsession', - reify=True - ) - - config.include('pyramid_tm') - - -def get_session(transaction_manager, dbmaker): - dbsession = dbmaker() - zope.sqlalchemy.register(dbsession, - transaction_manager=transaction_manager) - return dbsession - - -def get_engine(settings, prefix='sqlalchemy.'): - return engine_from_config(settings, prefix) - - -def get_dbmaker(engine): - dbmaker = sessionmaker() - dbmaker.configure(bind=engine) - return dbmaker diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py index 03e2f90ca..25209c745 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py @@ -1,15 +1,14 @@ -from .meta import Base - from pyramid.security import ( Allow, Everyone, - ) - +) from sqlalchemy import ( Column, Integer, Text, - ) +) + +from .meta import Base class Page(Base): @@ -19,8 +18,12 @@ class Page(Base): name = Column(Text, unique=True) data = Column(Integer) + class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] + __acl__ = [ + (Allow, Everyone, 'view'), + (Allow, 'group:editors', 'edit'), + ] + def __init__(self, request): - pass \ No newline at end of file + pass diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py index 4aac4a848..601a6e73f 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py @@ -7,13 +7,15 @@ from pyramid.paster import ( setup_logging, ) -from ..models.meta import ( - Base, - get_session, +from pyramid.scripts.common import parse_vars + +from ..models.meta import Base +from ..models import ( get_engine, - get_dbmaker, + get_session_factory, + get_tm_session, ) -from ..models.mymodel import Page +from ..models import Page def usage(argv): @@ -27,16 +29,17 @@ def main(argv=sys.argv): if len(argv) < 2: usage(argv) config_uri = argv[1] + options = parse_vars(argv[2:]) setup_logging(config_uri) - settings = get_appsettings(config_uri) + settings = get_appsettings(config_uri, options=options) engine = get_engine(settings) - dbmaker = get_dbmaker(engine) - - dbsession = get_session(transaction.manager, dbmaker) - Base.metadata.create_all(engine) + session_factory = get_session_factory(engine) + with transaction.manager: - model = Page(name='FrontPage', data='This is the front page') - dbsession.add(model) + dbsession = get_tm_session(session_factory, transaction.manager) + + page = Page(name='FrontPage', data='This is the front page') + dbsession.add(page) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py index 5bb534f79..e69de29bb 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py @@ -1 +0,0 @@ -# package diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py index d88c9c71f..7fc1ea7c8 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py @@ -1,6 +1,11 @@ -USERS = {'editor':'editor', - 'viewer':'viewer'} -GROUPS = {'editor':['group:editors']} +USERS = { + 'editor': 'editor', + 'viewer': 'viewer', +} + +GROUPS = { + 'editor': ['group:editors'], +} def groupfinder(userid, request): if userid in USERS: diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 new file mode 100644 index 000000000..1917f83c7 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
    +

    Pyramid Alchemy scaffold

    +

    404 Page Not Found

    +
    +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 index c4f3a2c93..70ce49b73 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 @@ -33,16 +33,16 @@
    - {% if logged_in %} + {% if request.authenticated_userid is not None %}

    - Logout + Logout

    {% endif %}

    Editing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %}

    You can return to the - FrontPage. + FrontPage.

    diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 index a7afc66fc..b12ca5b0c 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 @@ -33,9 +33,9 @@
    - {% if logged_in %} + {% if request.authenticated_userid is not None %}

    - Logout + Logout

    {% endif %}

    {{ content|safe }}

    @@ -48,7 +48,7 @@ Viewing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %}

    You can return to the - FrontPage. + FrontPage.

    diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index b947e3bb1..c54945c28 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -13,22 +13,22 @@ class BaseTest(unittest.TestCase): self.config = testing.setUp(settings={ 'sqlalchemy.url': 'sqlite:///:memory:' }) - self.config.include('.models.meta') + self.config.include('.models') settings = self.config.get_settings() - from .models.meta import ( - get_session, + from .models import ( get_engine, - get_dbmaker, + get_session_factory, + get_tm_session, ) self.engine = get_engine(settings) - dbmaker = get_dbmaker(self.engine) + session_factory = get_session_factory(self.engine) - self.session = get_session(transaction.manager, dbmaker) + self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models.meta import Base + from .models import Base Base.metadata.create_all(self.engine) def tearDown(self): @@ -36,7 +36,7 @@ class BaseTest(unittest.TestCase): testing.tearDown() transaction.abort() - Base.metadata.create_all(self.engine) + Base.metadata.drop_all(self.engine) class TestMyViewSuccessCondition(BaseTest): @@ -45,7 +45,7 @@ class TestMyViewSuccessCondition(BaseTest): super(TestMyViewSuccessCondition, self).setUp() self.init_database() - from .models.mymodel import MyModel + from .models import MyModel model = MyModel(name='one', value=55) self.session.add(model) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py index f35f041a4..aa77facd7 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -6,31 +6,27 @@ from pyramid.httpexceptions import ( HTTPFound, HTTPNotFound, ) - from pyramid.view import ( view_config, forbidden_view_config, ) - from pyramid.security import ( remember, forget, ) +from ..models import Page from ..security.default import USERS -from ..models.mymodel import Page - # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") -@view_config(route_name='view_wiki', - permission='view') +@view_config(route_name='view_wiki', permission='view') def view_wiki(request): - return HTTPFound(location=request.route_url('view_page', - pagename='FrontPage')) + next_url = request.route_url('view_page', pagename='FrontPage') + return HTTPFound(location=next_url) -@view_config(route_name='view_page', renderer='templates/view.jinja2', +@view_config(route_name='view_page', renderer='../templates/view.jinja2', permission='view') def view_page(request): pagename = request.matchdict['pagename'] @@ -51,10 +47,9 @@ def view_page(request): content = publish_parts(page.data, writer_name='html')['html_body'] content = wikiwords.sub(check, content) edit_url = request.route_url('edit_page', pagename=pagename) - return dict(page=page, content=content, edit_url=edit_url, - logged_in=request.authenticated_userid) + return dict(page=page, content=content, edit_url=edit_url) -@view_config(route_name='add_page', renderer='templates/edit.jinja2', +@view_config(route_name='add_page', renderer='../templates/edit.jinja2', permission='edit') def add_page(request): pagename = request.matchdict['pagename'] @@ -62,29 +57,27 @@ def add_page(request): body = request.params['body'] page = Page(name=pagename, data=body) request.dbsession.add(page) - return HTTPFound(location = request.route_url('view_page', - pagename=pagename)) + next_url = request.route_url('view_page', pagename=pagename) + return HTTPFound(location=next_url) save_url = request.route_url('add_page', pagename=pagename) page = Page(name='', data='') - return dict(page=page, save_url=save_url, - logged_in=request.authenticated_userid) + return dict(page=page, save_url=save_url) -@view_config(route_name='edit_page', renderer='templates/edit.jinja2', +@view_config(route_name='edit_page', renderer='../templates/edit.jinja2', permission='edit') def edit_page(request): pagename = request.matchdict['pagename'] page = request.dbsession.query(Page).filter_by(name=pagename).one() if 'form.submitted' in request.params: page.data = request.params['body'] - request.dbsession.add(page) - return HTTPFound(location = request.route_url('view_page', - pagename=pagename)) + next_url = request.route_url('view_page', pagename=pagename) + return HTTPFound(location=next_url) return dict( page=page, - save_url = request.route_url('edit_page', pagename=pagename), - logged_in=request.authenticated_userid + save_url=request.route_url('edit_page', pagename=pagename), ) + @view_config(route_name='login', renderer='templates/login.jinja2') @forbidden_view_config(renderer='templates/login.jinja2') def login(request): @@ -101,20 +94,19 @@ def login(request): password = request.params['password'] if USERS.get(login) == password: headers = remember(request, login) - return HTTPFound(location = came_from, - headers = headers) + return HTTPFound(location=came_from, headers=headers) message = 'Failed login' return dict( - message = message, - url = request.application_url + '/login', - came_from = came_from, - login = login, - password = password, + message=message, + url=request.route_url('login'), + came_from=came_from, + login=login, + password=password, ) @view_config(route_name='logout') def logout(request): headers = forget(request) - return HTTPFound(location = request.route_url('view_wiki'), - headers = headers) + next_url = request.route_url('view_wiki') + return HTTPFound(location=next_url, headers=headers) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py new file mode 100644 index 000000000..a4b8201f1 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py @@ -0,0 +1,5 @@ +from pyramid.view import notfound_view_config + +@notfound_view_config(renderer='../templates/404.jinja2') +def notfound_view(request): + return {} -- cgit v1.2.3 From 0b02e46ff9dafcdf9d4c03bac2958c8b20c596f6 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 8 Feb 2016 00:19:31 -0600 Subject: expose the session factory on the registry --- docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py | 1 + 1 file changed, 1 insertion(+) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py index 4810c357a..3d3efe06f 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py @@ -62,6 +62,7 @@ def includeme(config): config.include('pyramid_tm') session_factory = get_session_factory(get_engine(settings)) + config.registry['dbsession_factory'] = session_factory # make request.dbsession available for use in Pyramid config.add_request_method( -- cgit v1.2.3 From 91ffccabafd2f074ac7620b5b64e52a8eb3cb31a Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 8 Feb 2016 23:00:48 -0600 Subject: fix jinja2 none test --- docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 | 2 +- docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 index 70ce49b73..4d767cfbe 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 @@ -33,7 +33,7 @@
    - {% if request.authenticated_userid is not None %} + {% if request.authenticated_userid is not none %}

    Logout

    diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 index b12ca5b0c..942b8479b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 @@ -33,7 +33,7 @@
    - {% if request.authenticated_userid is not None %} + {% if request.authenticated_userid is not none %}

    Logout

    -- cgit v1.2.3 From 07d38f5d4c9ebaf267d4ecaf8c0bd4c508f1848f Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 10 Feb 2016 22:38:38 -0600 Subject: several simple refactorings - move auth from default.py to auth.py - rename errors to notfound - drop basic templates (mytemplate.jinja2, layout.jinja2) --- .../authorization/tutorial/templates/layout.jinja2 | 66 ---------------------- .../tutorial/templates/mytemplate.jinja2 | 8 --- .../wiki2/src/authorization/tutorial/views/auth.py | 49 ++++++++++++++++ .../src/authorization/tutorial/views/default.py | 44 +-------------- .../src/authorization/tutorial/views/errors.py | 5 -- .../src/authorization/tutorial/views/notfound.py | 7 +++ 6 files changed, 57 insertions(+), 122 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 deleted file mode 100644 index ff624c65b..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - Alchemy Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    - {% block content %} -

    No content

    - {% endblock content %} -
    -
    -
    - -
    -
    - -
    -
    -
    - - - - - - - - diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 deleted file mode 100644 index bb622bf5a..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/mytemplate.jinja2 +++ /dev/null @@ -1,8 +0,0 @@ -{% extends "layout.jinja2" %} - -{% block content %} -
    -

    Pyramid Alchemy scaffold

    -

    Welcome to {{project}}, an application generated by
    the Pyramid Web Framework 1.7.dev0.

    -
    -{% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py new file mode 100644 index 000000000..08aa2bfad --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py @@ -0,0 +1,49 @@ +from pyramid.httpexceptions import HTTPFound +from pyramid.security import ( + remember, + forget, + ) +from pyramid.view import ( + forbidden_view_config, + view_config, +) + +from ..security.default import USERS + + +@view_config(route_name='login', renderer='templates/login.jinja2') +def login(request): + login_url = request.route_url('login') + referrer = request.url + if referrer == login_url: + referrer = '/' # never use the login form itself as came_from + came_from = request.params.get('came_from', referrer) + message = '' + login = '' + password = '' + if 'form.submitted' in request.params: + login = request.params['login'] + password = request.params['password'] + if USERS.get(login) == password: + headers = remember(request, login) + return HTTPFound(location=came_from, headers=headers) + message = 'Failed login' + + return dict( + message=message, + url=request.route_url('login'), + came_from=came_from, + login=login, + password=password, + ) + +@view_config(route_name='logout') +def logout(request): + headers = forget(request) + next_url = request.route_url('view_wiki') + return HTTPFound(location=next_url, headers=headers) + +@forbidden_view_config() +def forbidden_view(request): + next_url = request.route_url('login', _query={'came_from': request.url}) + return HTTPFound(location=next_url) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py index aa77facd7..6fb3c8744 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -6,17 +6,9 @@ from pyramid.httpexceptions import ( HTTPFound, HTTPNotFound, ) -from pyramid.view import ( - view_config, - forbidden_view_config, - ) -from pyramid.security import ( - remember, - forget, - ) +from pyramid.view import view_config from ..models import Page -from ..security.default import USERS # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") @@ -76,37 +68,3 @@ def edit_page(request): page=page, save_url=request.route_url('edit_page', pagename=pagename), ) - - -@view_config(route_name='login', renderer='templates/login.jinja2') -@forbidden_view_config(renderer='templates/login.jinja2') -def login(request): - login_url = request.route_url('login') - referrer = request.url - if referrer == login_url: - referrer = '/' # never use the login form itself as came_from - came_from = request.params.get('came_from', referrer) - message = '' - login = '' - password = '' - if 'form.submitted' in request.params: - login = request.params['login'] - password = request.params['password'] - if USERS.get(login) == password: - headers = remember(request, login) - return HTTPFound(location=came_from, headers=headers) - message = 'Failed login' - - return dict( - message=message, - url=request.route_url('login'), - came_from=came_from, - login=login, - password=password, - ) - -@view_config(route_name='logout') -def logout(request): - headers = forget(request) - next_url = request.route_url('view_wiki') - return HTTPFound(location=next_url, headers=headers) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py deleted file mode 100644 index a4b8201f1..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/errors.py +++ /dev/null @@ -1,5 +0,0 @@ -from pyramid.view import notfound_view_config - -@notfound_view_config(renderer='../templates/404.jinja2') -def notfound_view(request): - return {} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py new file mode 100644 index 000000000..69d6e2804 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/notfound.py @@ -0,0 +1,7 @@ +from pyramid.view import notfound_view_config + + +@notfound_view_config(renderer='../templates/404.jinja2') +def notfound_view(request): + request.response.status = 404 + return {} -- cgit v1.2.3 From 9a7cfe3b4e248451750f5694255450bf1983e848 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 10 Feb 2016 23:54:51 -0600 Subject: update 404 templates --- docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 index 1917f83c7..37b0a16b6 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/404.jinja2 @@ -2,7 +2,7 @@ {% block content %}
    -

    Pyramid Alchemy scaffold

    +

    Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki)

    404 Page Not Found

    {% endblock content %} -- cgit v1.2.3 From f2e9c68e8168cfe51f7dc5ed86fea0471968f508 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Wed, 10 Feb 2016 23:55:03 -0600 Subject: move security into one place --- .../wiki2/src/authorization/tutorial/__init__.py | 11 +---- .../src/authorization/tutorial/models/mymodel.py | 14 ------ .../wiki2/src/authorization/tutorial/security.py | 51 ++++++++++++++++++++++ .../authorization/tutorial/security/__init__.py | 0 .../src/authorization/tutorial/security/default.py | 12 ----- 5 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/security.py delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/security/default.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index a62c42378..8eacdee5a 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -1,22 +1,13 @@ from pyramid.config import Configurator -from pyramid.authentication import AuthTktAuthenticationPolicy -from pyramid.authorization import ACLAuthorizationPolicy - -from .security.default import groupfinder def main(global_config, **settings): """ This function returns a Pyramid WSGI application. """ - authn_policy = AuthTktAuthenticationPolicy( - 'sosecret', callback=groupfinder, hashalg='sha512') - authz_policy = ACLAuthorizationPolicy() config = Configurator(settings=settings) config.include('pyramid_jinja2') config.include('.models') - config.set_root_factory('.models.mymodel.RootFactory') - config.set_authentication_policy(authn_policy) - config.set_authorization_policy(authz_policy) + config.include('.security') config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('view_wiki', '/') config.add_route('login', '/login') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py index 25209c745..b23d0c0d2 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py @@ -1,7 +1,3 @@ -from pyramid.security import ( - Allow, - Everyone, -) from sqlalchemy import ( Column, Integer, @@ -17,13 +13,3 @@ class Page(Base): id = Column(Integer, primary_key=True) name = Column(Text, unique=True) data = Column(Integer) - - -class RootFactory(object): - __acl__ = [ - (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit'), - ] - - def __init__(self, request): - pass diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security.py b/docs/tutorials/wiki2/src/authorization/tutorial/security.py new file mode 100644 index 000000000..7bceabf3f --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security.py @@ -0,0 +1,51 @@ +from pyramid.authentication import AuthTktAuthenticationPolicy +from pyramid.authorization import ACLAuthorizationPolicy + +from pyramid.security import ( + Allow, + Authenticated, + Everyone, +) + + +USERS = { + 'editor': 'editor', + 'viewer': 'viewer', +} + +GROUPS = { + 'editor': ['group:editors'], +} + +class MyAuthenticationPolicy(AuthTktAuthenticationPolicy): + def authenticated_userid(self, request): + userid = self.unauthenticated_userid(request) + if userid in USERS: + return userid + + def effective_principals(self, request): + principals = [Everyone] + userid = self.authenticated_userid(request) + if userid is not None: + principals.append(Authenticated) + principals.append(userid) + + groups = GROUPS.get(userid, []) + principals.extend(groups) + return principals + +class RootFactory(object): + __acl__ = [ + (Allow, Everyone, 'view'), + (Allow, 'group:editors', 'edit'), + ] + + def __init__(self, request): + pass + +def includeme(config): + authn_policy = MyAuthenticationPolicy('sosecret', hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() + config.set_root_factory(RootFactory) + config.set_authentication_policy(authn_policy) + config.set_authorization_policy(authz_policy) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/security/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py deleted file mode 100644 index 7fc1ea7c8..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/security/default.py +++ /dev/null @@ -1,12 +0,0 @@ -USERS = { - 'editor': 'editor', - 'viewer': 'viewer', -} - -GROUPS = { - 'editor': ['group:editors'], -} - -def groupfinder(userid, request): - if userid in USERS: - return GROUPS.get(userid, []) -- cgit v1.2.3 From cb5a84802171ed22b67958c7733cc0eddc680d34 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 11 Feb 2016 23:01:38 -0600 Subject: copy layout and templates from views to authorization --- .../authorization/tutorial/templates/edit.jinja2 | 93 +++++-------------- .../authorization/tutorial/templates/layout.jinja2 | 60 +++++++++++++ .../authorization/tutorial/templates/login.jinja2 | 100 ++++++--------------- .../authorization/tutorial/templates/view.jinja2 | 87 ++++-------------- .../src/authorization/tutorial/views/default.py | 2 +- 5 files changed, 123 insertions(+), 219 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 index 4d767cfbe..e47b3aabf 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 @@ -1,73 +1,20 @@ - - - - - - - - - - - Edit{% if page.name %} {{page.name}}{% endif %} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    - {% if request.authenticated_userid is not none %} -

    - Logout -

    - {% endif %} -

    - Editing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} -

    -

    You can return to the - FrontPage. -

    - -
    - -
    -
    - -
    - -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - +{% extends 'layout.jinja2' %} + +{% block title %}Edit {{page.name}} - {% endblock title %} + +{% block content %} +

    +Editing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +

    +

    You can return to the +FrontPage. +

    +
    +
    + +
    +
    + +
    +
    +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 new file mode 100644 index 000000000..82a144abf --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 @@ -0,0 +1,60 @@ + + + + + + + + + + + {% block title %}{% if page.name %} {{page.name}} - {% endif %}{% endblock title %}Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + + + + + + + + + + + + + +
    +
    +
    +
    + +
    +
    +
    + {% if request.authenticated_userid is not none %} +

    + Logout +

    + {% endif %} + {% block content %}{% endblock %} +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 index a80a2a165..99d369173 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 @@ -1,74 +1,26 @@ - - - - - - - - - - - Login - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    -

    - - Login -
    - {{ message }} -

    -
    - -
    - - -
    -
    - - -
    -
    - -
    -
    -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - +{% extends 'layout.jinja2' %} + +{% block title %}Login - {% endblock title %} + +{% block content %} +

    + + Login +
    +{{ message }} +

    +
    + +
    + + +
    +
    + + +
    +
    + +
    +
    +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 index 942b8479b..c582ce1f9 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 @@ -1,71 +1,16 @@ - - - - - - - - - - - {{page.name}} - Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) - - - - - - - - - - - - - -
    -
    -
    -
    - -
    -
    -
    - {% if request.authenticated_userid is not none %} -

    - Logout -

    - {% endif %} -

    {{ content|safe }}

    -

    - - Edit this page - -

    -

    - Viewing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} -

    -

    You can return to the - FrontPage. -

    -
    -
    -
    -
    - -
    -
    -
    - - - - - - - - +{% extends 'layout.jinja2' %} + +{% block content %} +

    {{ content|safe }}

    +

    + + Edit this page + +

    +

    + Viewing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +

    +

    You can return to the +FrontPage. +

    +{% endblock content %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py index 6fb3c8744..e152e73e0 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -24,7 +24,7 @@ def view_page(request): pagename = request.matchdict['pagename'] page = request.dbsession.query(Page).filter_by(name=pagename).first() if page is None: - return HTTPNotFound('No such page') + raise HTTPNotFound('No such page') def check(match): word = match.group(1) -- cgit v1.2.3 From 81e5989ed5b2bd7ea1a2b843dea9726b253b38ce Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 12 Feb 2016 00:18:40 -0600 Subject: create an actual user model to prepare for security --- docs/tutorials/wiki2/src/authorization/tutorial/views/default.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py index e152e73e0..f74059be0 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -10,6 +10,7 @@ from pyramid.view import view_config from ..models import Page + # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") @@ -42,7 +43,7 @@ def view_page(request): return dict(page=page, content=content, edit_url=edit_url) @view_config(route_name='add_page', renderer='../templates/edit.jinja2', - permission='edit') + permission='create') def add_page(request): pagename = request.matchdict['pagename'] if 'form.submitted' in request.params: -- cgit v1.2.3 From 4872a1e713f894b383990f62cf82c2b21f810c16 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Fri, 12 Feb 2016 02:48:09 -0600 Subject: forward port changes to models / scripts to later chapters --- docs/tutorials/wiki2/src/authorization/setup.py | 3 ++- .../src/authorization/tutorial/models/__init__.py | 3 ++- .../src/authorization/tutorial/models/mymodel.py | 15 ------------ .../src/authorization/tutorial/models/page.py | 20 ++++++++++++++++ .../src/authorization/tutorial/models/user.py | 27 ++++++++++++++++++++++ .../authorization/tutorial/scripts/initializedb.py | 16 +++++++++++-- 6 files changed, 65 insertions(+), 19 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models/page.py create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/models/user.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index d4e5a4072..c342c1aba 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -9,6 +9,8 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ + 'bcrypt', + 'docutils', 'pyramid', 'pyramid_jinja2', 'pyramid_debugtoolbar', @@ -17,7 +19,6 @@ requires = [ 'transaction', 'zope.sqlalchemy', 'waitress', - 'docutils', ] setup(name='tutorial', diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py index 3d3efe06f..a8871f6f5 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/__init__.py @@ -5,7 +5,8 @@ import zope.sqlalchemy # import or define all models here to ensure they are attached to the # Base.metadata prior to any initialization routines -from .mymodel import Page # flake8: noqa +from .page import Page # flake8: noqa +from .user import User # flake8: noqa # run configure_mappers after defining all of the models to ensure # all relationships can be setup diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py deleted file mode 100644 index b23d0c0d2..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/mymodel.py +++ /dev/null @@ -1,15 +0,0 @@ -from sqlalchemy import ( - Column, - Integer, - Text, -) - -from .meta import Base - - -class Page(Base): - """ The SQLAlchemy declarative model class for a Page object. """ - __tablename__ = 'pages' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - data = Column(Integer) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py new file mode 100644 index 000000000..4dd5b5721 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/page.py @@ -0,0 +1,20 @@ +from sqlalchemy import ( + Column, + ForeignKey, + Integer, + Text, +) +from sqlalchemy.orm import relationship + +from .meta import Base + + +class Page(Base): + """ The SQLAlchemy declarative model class for a Page object. """ + __tablename__ = 'pages' + id = Column(Integer, primary_key=True) + name = Column(Text, nullable=False, unique=True) + data = Column(Integer, nullable=False) + + creator_id = Column(ForeignKey('users.id'), nullable=False) + creator = relationship('User', backref='created_pages') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py new file mode 100644 index 000000000..25b0a8187 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py @@ -0,0 +1,27 @@ +import bcrypt +from sqlalchemy import ( + Column, + Integer, + Text, +) + +from .meta import Base + + +class User(Base): + """ The SQLAlchemy declarative model class for a User object. """ + __tablename__ = 'users' + id = Column(Integer, primary_key=True) + name = Column(Text, nullable=False, unique=True) + role = Column(Text, nullable=False) + + password_hash = Column(Text) + + def set_password(self, pw): + pwhash = bcrypt.hashpw(pw, bcrypt.gensalt()) + self.password_hash = pwhash + + def check_password(self, pw): + if self.password_hash is not None: + return bcrypt.hashpw(pw, self.password_hash) == self.password_hash + return False diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py index 601a6e73f..f3c0a6fef 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/scripts/initializedb.py @@ -15,7 +15,7 @@ from ..models import ( get_session_factory, get_tm_session, ) -from ..models import Page +from ..models import Page, User def usage(argv): @@ -41,5 +41,17 @@ def main(argv=sys.argv): with transaction.manager: dbsession = get_tm_session(session_factory, transaction.manager) - page = Page(name='FrontPage', data='This is the front page') + editor = User(name='editor', role='editor') + editor.set_password('editor') + dbsession.add(editor) + + basic = User(name='basic', role='basic') + basic.set_password('basic') + dbsession.add(basic) + + page = Page( + name='FrontPage', + creator=editor, + data='This is the front page', + ) dbsession.add(page) -- cgit v1.2.3 From 2fa90465bfdd213b6ce51ca8de6eaf9b614c283e Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Tue, 16 Feb 2016 23:42:04 -0600 Subject: add first cut at source for authorization chapter --- .../wiki2/src/authorization/development.ini | 2 + .../wiki2/src/authorization/production.ini | 2 + .../wiki2/src/authorization/tutorial/__init__.py | 8 +--- .../src/authorization/tutorial/models/user.py | 6 ++- .../wiki2/src/authorization/tutorial/routes.py | 50 ++++++++++++++++++++ .../wiki2/src/authorization/tutorial/security.py | 51 ++++++++------------- .../authorization/tutorial/templates/edit.jinja2 | 6 +-- .../authorization/tutorial/templates/layout.jinja2 | 10 ++-- .../authorization/tutorial/templates/login.jinja2 | 4 +- .../authorization/tutorial/templates/view.jinja2 | 4 +- .../wiki2/src/authorization/tutorial/views/auth.py | 23 ++++------ .../src/authorization/tutorial/views/default.py | 53 ++++++++++------------ 12 files changed, 126 insertions(+), 93 deletions(-) create mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/routes.py (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index 99c4ff0fe..f3079727e 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -17,6 +17,8 @@ pyramid.includes = sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +auth.secret = seekrit + # By default, the toolbar only appears for clients from IP addresses # '127.0.0.1' and '::1'. # debugtoolbar.hosts = 127.0.0.1 ::1 diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index cb1db3211..686dba48a 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -14,6 +14,8 @@ pyramid.default_locale_name = en sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite +auth.secret = real-seekrit + [server:main] use = egg:waitress#main host = 0.0.0.0 diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py index 8eacdee5a..f5c033b8b 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/__init__.py @@ -7,13 +7,7 @@ def main(global_config, **settings): config = Configurator(settings=settings) config.include('pyramid_jinja2') config.include('.models') + config.include('.routes') config.include('.security') - config.add_static_view('static', 'static', cache_max_age=3600) - config.add_route('view_wiki', '/') - config.add_route('login', '/login') - config.add_route('logout', '/logout') - config.add_route('view_page', '/{pagename}') - config.add_route('add_page', '/add_page/{pagename}') - config.add_route('edit_page', '/{pagename}/edit_page') config.scan() return config.make_wsgi_app() diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py index 25b0a8187..6fb32a1b2 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py @@ -18,10 +18,12 @@ class User(Base): password_hash = Column(Text) def set_password(self, pw): - pwhash = bcrypt.hashpw(pw, bcrypt.gensalt()) + pwhash = bcrypt.hashpw(pw.encode('utf8'), bcrypt.gensalt()) self.password_hash = pwhash def check_password(self, pw): if self.password_hash is not None: - return bcrypt.hashpw(pw, self.password_hash) == self.password_hash + expected_hash = self.password_hash.encode('utf8') + actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) + return expected_hash == actual_hash return False diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/routes.py b/docs/tutorials/wiki2/src/authorization/tutorial/routes.py new file mode 100644 index 000000000..c7c3a2120 --- /dev/null +++ b/docs/tutorials/wiki2/src/authorization/tutorial/routes.py @@ -0,0 +1,50 @@ +from pyramid.httpexceptions import HTTPNotFound +from pyramid.security import ( + Allow, + Everyone, +) + +from .models import Page + +def includeme(config): + config.add_static_view('static', 'static', cache_max_age=3600) + config.add_route('view_wiki', '/') + config.add_route('login', '/login') + config.add_route('logout', '/logout') + config.add_route('view_page', '/{pagename}', factory=page_factory) + config.add_route('add_page', '/add_page/{pagename}', + factory=new_page_factory) + config.add_route('edit_page', '/{pagename}/edit_page', + factory=page_factory) + +def new_page_factory(request): + pagename = request.matchdict['pagename'] + return NewPage(pagename) + +class NewPage(object): + def __init__(self, pagename): + self.pagename = pagename + + def __acl__(self): + return [ + (Allow, 'role:editor', 'create'), + (Allow, 'role:basic', 'create'), + ] + +def page_factory(request): + pagename = request.matchdict['pagename'] + page = request.dbsession.query(Page).filter_by(name=pagename).first() + if page is None: + raise HTTPNotFound + return PageResource(page) + +class PageResource(object): + def __init__(self, page): + self.page = page + + def __acl__(self): + return [ + (Allow, Everyone, 'view'), + (Allow, 'role:editor', 'edit'), + (Allow, str(self.page.creator_id), 'edit'), + ] diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/security.py b/docs/tutorials/wiki2/src/authorization/tutorial/security.py index 7bceabf3f..25cff7b05 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/security.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/security.py @@ -1,51 +1,40 @@ from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy - from pyramid.security import ( - Allow, Authenticated, Everyone, ) +from .models import User -USERS = { - 'editor': 'editor', - 'viewer': 'viewer', -} - -GROUPS = { - 'editor': ['group:editors'], -} class MyAuthenticationPolicy(AuthTktAuthenticationPolicy): def authenticated_userid(self, request): - userid = self.unauthenticated_userid(request) - if userid in USERS: - return userid + user = request.user + if user is not None: + return user.id def effective_principals(self, request): principals = [Everyone] - userid = self.authenticated_userid(request) - if userid is not None: + user = request.user + if user is not None: principals.append(Authenticated) - principals.append(userid) - - groups = GROUPS.get(userid, []) - principals.extend(groups) + principals.append(str(user.id)) + principals.append('role:' + user.role) return principals -class RootFactory(object): - __acl__ = [ - (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit'), - ] - - def __init__(self, request): - pass +def get_user(request): + user_id = request.unauthenticated_userid + if user_id is not None: + user = request.dbsession.query(User).get(user_id) + return user def includeme(config): - authn_policy = MyAuthenticationPolicy('sosecret', hashalg='sha512') - authz_policy = ACLAuthorizationPolicy() - config.set_root_factory(RootFactory) + settings = config.get_settings() + authn_policy = MyAuthenticationPolicy( + settings['auth.secret'], + hashalg='sha512', + ) config.set_authentication_policy(authn_policy) - config.set_authorization_policy(authz_policy) + config.set_authorization_policy(ACLAuthorizationPolicy()) + config.add_request_method(get_user, 'user', reify=True) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 index e47b3aabf..7db25c674 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/edit.jinja2 @@ -1,17 +1,17 @@ {% extends 'layout.jinja2' %} -{% block title %}Edit {{page.name}} - {% endblock title %} +{% block subtitle %}Edit {{pagename}} - {% endblock subtitle %} {% block content %}

    -Editing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} +Editing {{pagename}}

    You can return to the FrontPage.

    - +
    diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 index 82a144abf..44d14304e 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/layout.jinja2 @@ -8,7 +8,7 @@ - {% block title %}{% if page.name %} {{page.name}} - {% endif %}{% endblock title %}Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) + {% block subtitle %}{% endblock %}Pyramid tutorial wiki (based on TurboGears 20-Minute Wiki) @@ -33,9 +33,13 @@
    - {% if request.authenticated_userid is not none %} + {% if request.user is none %}

    - Logout + Login +

    + {% else %} +

    + {{request.user.name}} Logout

    {% endif %} {% block content %}{% endblock %} diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 index 99d369173..1806de0ff 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/login.jinja2 @@ -10,14 +10,14 @@ {{ message }}

    - +
    - +
    diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 index c582ce1f9..94419e228 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 +++ b/docs/tutorials/wiki2/src/authorization/tutorial/templates/view.jinja2 @@ -1,5 +1,7 @@ {% extends 'layout.jinja2' %} +{% block subtitle %}{{page.name}} - {% endblock subtitle %} + {% block content %}

    {{ content|safe }}

    @@ -8,7 +10,7 @@

    - Viewing {% if page.name %}{{page.name}}{% else %}Page Name Goes Here{% endif %} + Viewing {{page.name}}, created by {{page.creator.name}}.

    You can return to the FrontPage. diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py index 08aa2bfad..d3db34132 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py @@ -8,33 +8,28 @@ from pyramid.view import ( view_config, ) -from ..security.default import USERS +from ..models import User -@view_config(route_name='login', renderer='templates/login.jinja2') +@view_config(route_name='login', renderer='../templates/login.jinja2') def login(request): - login_url = request.route_url('login') - referrer = request.url - if referrer == login_url: - referrer = '/' # never use the login form itself as came_from - came_from = request.params.get('came_from', referrer) + next_url = request.params.get('next', request.referrer) message = '' login = '' - password = '' if 'form.submitted' in request.params: login = request.params['login'] password = request.params['password'] - if USERS.get(login) == password: - headers = remember(request, login) - return HTTPFound(location=came_from, headers=headers) + user = request.dbsession.query(User).filter_by(name=login).first() + if user is not None and user.check_password(password): + headers = remember(request, user.id) + return HTTPFound(location=next_url, headers=headers) message = 'Failed login' return dict( message=message, url=request.route_url('login'), - came_from=came_from, + next_url=next_url, login=login, - password=password, ) @view_config(route_name='logout') @@ -45,5 +40,5 @@ def logout(request): @forbidden_view_config() def forbidden_view(request): - next_url = request.route_url('login', _query={'came_from': request.url}) + next_url = request.route_url('login', _query={'next': request.url}) return HTTPFound(location=next_url) diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py index f74059be0..9358993ea 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/default.py @@ -2,19 +2,15 @@ import cgi import re from docutils.core import publish_parts -from pyramid.httpexceptions import ( - HTTPFound, - HTTPNotFound, - ) +from pyramid.httpexceptions import HTTPFound from pyramid.view import view_config from ..models import Page - # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") -@view_config(route_name='view_wiki', permission='view') +@view_config(route_name='view_wiki') def view_wiki(request): next_url = request.route_url('view_page', pagename='FrontPage') return HTTPFound(location=next_url) @@ -22,12 +18,9 @@ def view_wiki(request): @view_config(route_name='view_page', renderer='../templates/view.jinja2', permission='view') def view_page(request): - pagename = request.matchdict['pagename'] - page = request.dbsession.query(Page).filter_by(name=pagename).first() - if page is None: - raise HTTPNotFound('No such page') + page = request.context.page - def check(match): + def add_link(match): word = match.group(1) exists = request.dbsession.query(Page).filter_by(name=word).all() if exists: @@ -38,34 +31,34 @@ def view_page(request): return '%s' % (add_url, cgi.escape(word)) content = publish_parts(page.data, writer_name='html')['html_body'] - content = wikiwords.sub(check, content) - edit_url = request.route_url('edit_page', pagename=pagename) + content = wikiwords.sub(add_link, content) + edit_url = request.route_url('edit_page', pagename=page.name) return dict(page=page, content=content, edit_url=edit_url) +@view_config(route_name='edit_page', renderer='../templates/edit.jinja2', + permission='edit') +def edit_page(request): + page = request.context.page + if 'form.submitted' in request.params: + page.data = request.params['body'] + next_url = request.route_url('view_page', pagename=page.name) + return HTTPFound(location=next_url) + return dict( + pagename=page.name, + pagedata=page.data, + save_url=request.route_url('edit_page', pagename=page.name), + ) + @view_config(route_name='add_page', renderer='../templates/edit.jinja2', permission='create') def add_page(request): - pagename = request.matchdict['pagename'] + pagename = request.context.pagename if 'form.submitted' in request.params: body = request.params['body'] page = Page(name=pagename, data=body) + page.creator = request.user request.dbsession.add(page) next_url = request.route_url('view_page', pagename=pagename) return HTTPFound(location=next_url) save_url = request.route_url('add_page', pagename=pagename) - page = Page(name='', data='') - return dict(page=page, save_url=save_url) - -@view_config(route_name='edit_page', renderer='../templates/edit.jinja2', - permission='edit') -def edit_page(request): - pagename = request.matchdict['pagename'] - page = request.dbsession.query(Page).filter_by(name=pagename).one() - if 'form.submitted' in request.params: - page.data = request.params['body'] - next_url = request.route_url('view_page', pagename=pagename) - return HTTPFound(location=next_url) - return dict( - page=page, - save_url=request.route_url('edit_page', pagename=pagename), - ) + return dict(pagename=pagename, pagedata='', save_url=save_url) -- cgit v1.2.3 From 91f7ed469664bf71f98b6e55ea096f5bdddae953 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 18 Feb 2016 01:53:49 -0600 Subject: add webtest and tests_require to setup.py --- docs/tutorials/wiki2/src/authorization/setup.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index c342c1aba..57538f2d0 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -21,6 +21,10 @@ requires = [ 'waitress', ] +tests_require = [ + 'WebTest', +] + setup(name='tutorial', version='0.0', description='tutorial', @@ -39,6 +43,7 @@ setup(name='tutorial', include_package_data=True, zip_safe=False, test_suite='tutorial', + tests_require=tests_require, install_requires=requires, entry_points="""\ [paste.app_factory] -- cgit v1.2.3 From 50e08a743d097616ef7f76c9689833eab215cb94 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Thu, 18 Feb 2016 02:22:26 -0600 Subject: add fallback for next_url --- docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py index d3db34132..2b993b430 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/views/auth.py @@ -14,6 +14,8 @@ from ..models import User @view_config(route_name='login', renderer='../templates/login.jinja2') def login(request): next_url = request.params.get('next', request.referrer) + if not next_url: + next_url = request.route_url('view_wiki') message = '' login = '' if 'form.submitted' in request.params: -- cgit v1.2.3 From a26a08b92f390aeaa3eb0c39241bb5e76f5a72ea Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 28 Feb 2016 01:29:55 -0800 Subject: apply change to all src/*/user.py --- docs/tutorials/wiki2/src/authorization/tutorial/models/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py index 6fb32a1b2..6bd3315d6 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/models/user.py @@ -23,7 +23,7 @@ class User(Base): def check_password(self, pw): if self.password_hash is not None: - expected_hash = self.password_hash.encode('utf8') + expected_hash = self.password_hash actual_hash = bcrypt.hashpw(pw.encode('utf8'), expected_hash) return expected_hash == actual_hash return False -- cgit v1.2.3 From 3e30040da7c2d5c38b330727b48d9f6b852956d9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sun, 28 Feb 2016 22:30:22 -0800 Subject: redirect to edit page when user attempts to add page that already exists - update src/*/views/default.py - update src/*/routes.py - write new test - revise docs, double-checking line counts and highlighting --- docs/tutorials/wiki2/src/authorization/tutorial/routes.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/routes.py b/docs/tutorials/wiki2/src/authorization/tutorial/routes.py index c7c3a2120..f0a8b7f96 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/routes.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/routes.py @@ -1,4 +1,7 @@ -from pyramid.httpexceptions import HTTPNotFound +from pyramid.httpexceptions import ( + HTTPNotFound, + HTTPFound, +) from pyramid.security import ( Allow, Everyone, @@ -19,6 +22,9 @@ def includeme(config): def new_page_factory(request): pagename = request.matchdict['pagename'] + if request.dbsession.query(Page).filter_by(name=pagename).count() > 0: + next_url = request.route_url('edit_page', pagename=pagename) + raise HTTPFound(location=next_url) return NewPage(pagename) class NewPage(object): -- cgit v1.2.3 From 50642ec0d3705db51564d1511695da53f63ff82b Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Sat, 9 Apr 2016 14:05:23 -0700 Subject: - update wiki2/authorization step --- .../wiki2/src/authorization/development.ini | 4 ++-- .../wiki2/src/authorization/production.ini | 4 ++-- docs/tutorials/wiki2/src/authorization/setup.py | 23 ++++++++++++---------- .../wiki2/src/authorization/tutorial/tests.py | 2 +- 4 files changed, 18 insertions(+), 15 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini index f3079727e..4a6c9325c 100644 --- a/docs/tutorials/wiki2/src/authorization/development.ini +++ b/docs/tutorials/wiki2/src/authorization/development.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html ### [app:main] @@ -34,7 +34,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini index 686dba48a..a13a0ca19 100644 --- a/docs/tutorials/wiki2/src/authorization/production.ini +++ b/docs/tutorials/wiki2/src/authorization/production.ini @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/environment.html ### [app:main] @@ -23,7 +23,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/1.7-branch/narr/logging.html ### [loggers] diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 57538f2d0..8dca906c8 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -21,20 +21,22 @@ requires = [ 'waitress', ] -tests_require = [ - 'WebTest', -] +testing_extras = [ + 'WebTest >= 1.3.1', # py3 compat + 'pytest', # includes virtualenv + 'pytest-cov', + ] setup(name='tutorial', version='0.0', description='tutorial', long_description=README + '\n\n' + CHANGES, classifiers=[ - "Programming Language :: Python", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], + "Programming Language :: Python", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], author='', author_email='', url='', @@ -42,8 +44,9 @@ setup(name='tutorial', packages=find_packages(), include_package_data=True, zip_safe=False, - test_suite='tutorial', - tests_require=tests_require, + extras_require={ + 'testing': testing_extras, + }, install_requires=requires, entry_points="""\ [paste.app_factory] diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py index c54945c28..99e95efd3 100644 --- a/docs/tutorials/wiki2/src/authorization/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/authorization/tutorial/tests.py @@ -28,7 +28,7 @@ class BaseTest(unittest.TestCase): self.session = get_tm_session(session_factory, transaction.manager) def init_database(self): - from .models import Base + from .models.meta import Base Base.metadata.create_all(self.engine) def tearDown(self): -- cgit v1.2.3 From f9a67aa2f725d9375fb00321b67c2bfa211b4cff Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 11 Apr 2016 21:26:24 -0500 Subject: fix readme to show directions in both alchemy and zodb --- docs/tutorials/wiki2/src/authorization/README.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/README.txt b/docs/tutorials/wiki2/src/authorization/README.txt index 68f430110..5b0101e5f 100644 --- a/docs/tutorials/wiki2/src/authorization/README.txt +++ b/docs/tutorials/wiki2/src/authorization/README.txt @@ -6,7 +6,7 @@ Getting Started - cd -- $VENV/bin/python setup.py develop +- $VENV/bin/pip install -e . - $VENV/bin/initialize_tutorial_db development.ini -- cgit v1.2.3 From db3aa086a25504f8faf0149875eb7ff73ef08352 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Mon, 11 Apr 2016 21:26:46 -0500 Subject: remove theme.min.css, it serves no purpose --- docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css | 1 - 1 file changed, 1 deletion(-) delete mode 100644 docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css deleted file mode 100644 index 0d25de5b6..000000000 --- a/docs/tutorials/wiki2/src/authorization/tutorial/static/theme.min.css +++ /dev/null @@ -1 +0,0 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a,a{color:#f2b7bd;text-decoration:underline}.starter-template .links ul li a:hover,a:hover{color:#fff;text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} -- cgit v1.2.3 From ebbe68144ad6a6022863aa4a29f5611fde02258f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 12 Apr 2016 04:52:20 -0700 Subject: - use an environment variable and venv. See https://github.com/Pylons/pyramid/pull/2468#discussion_r59311019 - rename stanza from `testing_extras` to `tests_require` - switch from nose to pytest --- docs/tutorials/wiki2/src/authorization/setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/tutorials/wiki2/src/authorization') diff --git a/docs/tutorials/wiki2/src/authorization/setup.py b/docs/tutorials/wiki2/src/authorization/setup.py index 8dca906c8..def3ce1f6 100644 --- a/docs/tutorials/wiki2/src/authorization/setup.py +++ b/docs/tutorials/wiki2/src/authorization/setup.py @@ -21,7 +21,7 @@ requires = [ 'waitress', ] -testing_extras = [ +tests_require = [ 'WebTest >= 1.3.1', # py3 compat 'pytest', # includes virtualenv 'pytest-cov', @@ -45,7 +45,7 @@ setup(name='tutorial', include_package_data=True, zip_safe=False, extras_require={ - 'testing': testing_extras, + 'testing': tests_require, }, install_requires=requires, entry_points="""\ -- cgit v1.2.3