From b1b92284f496800a4dfd2cea72cb9be07ba8661c Mon Sep 17 00:00:00 2001 From: Paul Everitt Date: Fri, 13 Sep 2013 16:52:14 -0400 Subject: First cut at import of quick tutorial. --- docs/quick_tutorial/authorization/development.ini | 42 ++++++++++++++ docs/quick_tutorial/authorization/setup.py | 13 +++++ .../authorization/tutorial/__init__.py | 25 ++++++++ docs/quick_tutorial/authorization/tutorial/home.pt | 18 ++++++ .../quick_tutorial/authorization/tutorial/login.pt | 25 ++++++++ .../authorization/tutorial/resources.py | 9 +++ .../authorization/tutorial/security.py | 8 +++ .../quick_tutorial/authorization/tutorial/tests.py | 47 +++++++++++++++ .../quick_tutorial/authorization/tutorial/views.py | 66 ++++++++++++++++++++++ 9 files changed, 253 insertions(+) create mode 100644 docs/quick_tutorial/authorization/development.ini create mode 100644 docs/quick_tutorial/authorization/setup.py create mode 100644 docs/quick_tutorial/authorization/tutorial/__init__.py create mode 100644 docs/quick_tutorial/authorization/tutorial/home.pt create mode 100644 docs/quick_tutorial/authorization/tutorial/login.pt create mode 100644 docs/quick_tutorial/authorization/tutorial/resources.py create mode 100644 docs/quick_tutorial/authorization/tutorial/security.py create mode 100644 docs/quick_tutorial/authorization/tutorial/tests.py create mode 100644 docs/quick_tutorial/authorization/tutorial/views.py (limited to 'docs/quick_tutorial/authorization') diff --git a/docs/quick_tutorial/authorization/development.ini b/docs/quick_tutorial/authorization/development.ini new file mode 100644 index 000000000..5d4580ff5 --- /dev/null +++ b/docs/quick_tutorial/authorization/development.ini @@ -0,0 +1,42 @@ +[app:main] +use = egg:tutorial +pyramid.reload_templates = true +pyramid.includes = + pyramid_debugtoolbar +tutorial.secret = 98zd + +[server:main] +use = egg:pyramid#wsgiref +host = 0.0.0.0 +port = 6543 + +# Begin logging configuration + +[loggers] +keys = root, tutorial + +[logger_tutorial] +level = DEBUG +handlers = +qualname = tutorial + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/docs/quick_tutorial/authorization/setup.py b/docs/quick_tutorial/authorization/setup.py new file mode 100644 index 000000000..9997984d3 --- /dev/null +++ b/docs/quick_tutorial/authorization/setup.py @@ -0,0 +1,13 @@ +from setuptools import setup + +requires = [ + 'pyramid', +] + +setup(name='tutorial', + install_requires=requires, + entry_points="""\ + [paste.app_factory] + main = tutorial:main + """, +) \ No newline at end of file diff --git a/docs/quick_tutorial/authorization/tutorial/__init__.py b/docs/quick_tutorial/authorization/tutorial/__init__.py new file mode 100644 index 000000000..715a14203 --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/__init__.py @@ -0,0 +1,25 @@ +from pyramid.authentication import AuthTktAuthenticationPolicy +from pyramid.authorization import ACLAuthorizationPolicy +from pyramid.config import Configurator + +from .security import groupfinder + + +def main(global_config, **settings): + config = Configurator(settings=settings, + root_factory='.resources.Root') + + # Security policies + authn_policy = AuthTktAuthenticationPolicy( + settings['tutorial.secret'], callback=groupfinder, + hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() + config.set_authentication_policy(authn_policy) + config.set_authorization_policy(authz_policy) + + config.add_route('home', '/') + config.add_route('hello', '/howdy') + config.add_route('login', '/login') + config.add_route('logout', '/logout') + config.scan('.views') + return config.make_wsgi_app() \ No newline at end of file diff --git a/docs/quick_tutorial/authorization/tutorial/home.pt b/docs/quick_tutorial/authorization/tutorial/home.pt new file mode 100644 index 000000000..6ecd0081b --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/home.pt @@ -0,0 +1,18 @@ + + + + Quick Tour: ${name} + + + +
+ Log In + Logout +
+ +

Hi ${name}

+

Visit hello

+ + \ No newline at end of file diff --git a/docs/quick_tutorial/authorization/tutorial/login.pt b/docs/quick_tutorial/authorization/tutorial/login.pt new file mode 100644 index 000000000..4451fc4f8 --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/login.pt @@ -0,0 +1,25 @@ + + + + Quick Tour: ${name} + + +

Login

+ + +
+ + +
+ +
+ +
+ + \ No newline at end of file diff --git a/docs/quick_tutorial/authorization/tutorial/resources.py b/docs/quick_tutorial/authorization/tutorial/resources.py new file mode 100644 index 000000000..0cb656f12 --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/resources.py @@ -0,0 +1,9 @@ +from pyramid.security import Allow, Everyone + + +class Root(object): + __acl__ = [(Allow, Everyone, 'view'), + (Allow, 'group:editors', 'edit')] + + def __init__(self, request): + pass \ No newline at end of file diff --git a/docs/quick_tutorial/authorization/tutorial/security.py b/docs/quick_tutorial/authorization/tutorial/security.py new file mode 100644 index 000000000..ab90bab2c --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/security.py @@ -0,0 +1,8 @@ +USERS = {'editor': 'editor', + 'viewer': 'viewer'} +GROUPS = {'editor': ['group:editors']} + + +def groupfinder(userid, request): + if userid in USERS: + return GROUPS.get(userid, []) \ No newline at end of file diff --git a/docs/quick_tutorial/authorization/tutorial/tests.py b/docs/quick_tutorial/authorization/tutorial/tests.py new file mode 100644 index 000000000..6ff554a1e --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/tests.py @@ -0,0 +1,47 @@ +import unittest + +from pyramid import testing + + +class TutorialViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_home(self): + from .views import TutorialViews + + request = testing.DummyRequest() + inst = TutorialViews(request) + response = inst.home() + self.assertEqual('Home View', response['name']) + + def test_hello(self): + from .views import TutorialViews + + request = testing.DummyRequest() + inst = TutorialViews(request) + response = inst.hello() + self.assertEqual('Hello View', response['name']) + + +class TutorialFunctionalTests(unittest.TestCase): + def setUp(self): + from tutorial import main + app = main({}) + from webtest import TestApp + + self.testapp = TestApp(app) + + def tearDown(self): + testing.tearDown() + + def test_home(self): + res = self.testapp.get('/', status=200) + self.assertIn(b'

Hi Home View', res.body) + + def test_hello(self): + res = self.testapp.get('/howdy', status=200) + self.assertIn(b'

Hi Hello View', res.body) diff --git a/docs/quick_tutorial/authorization/tutorial/views.py b/docs/quick_tutorial/authorization/tutorial/views.py new file mode 100644 index 000000000..92c1946ba --- /dev/null +++ b/docs/quick_tutorial/authorization/tutorial/views.py @@ -0,0 +1,66 @@ +from pyramid.httpexceptions import HTTPFound +from pyramid.security import ( + remember, + forget, + authenticated_userid + ) +from pyramid.view import ( + view_config, + view_defaults, + forbidden_view_config + ) + +from .security import USERS + + +@view_defaults(renderer='home.pt') +class TutorialViews: + def __init__(self, request): + self.request = request + self.logged_in = authenticated_userid(request) + + @view_config(route_name='home') + def home(self): + return {'name': 'Home View'} + + @view_config(route_name='hello', permission='edit') + def hello(self): + return {'name': 'Hello View'} + + @view_config(route_name='login', renderer='login.pt') + @forbidden_view_config(renderer='login.pt') + def login(self): + request = self.request + login_url = request.route_url('login') + referrer = request.url + if referrer == login_url: + referrer = '/' # never use 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( + name='Login', + message=message, + url=request.application_url + '/login', + came_from=came_from, + login=login, + password=password, + ) + + @view_config(route_name='logout') + def logout(self): + request = self.request + headers = forget(request) + url = request.route_url('home') + return HTTPFound(location=url, + headers=headers) -- cgit v1.2.3