Skip to content

Commit

Permalink
Merge pull request #3760 from Pylons/tseaver-qt_cleanup
Browse files Browse the repository at this point in the history
docs: quick tutorial cleanups
  • Loading branch information
tseaver authored Jun 10, 2024
2 parents 72f6185 + 1ebd988 commit ef0f686
Show file tree
Hide file tree
Showing 17 changed files with 62 additions and 276 deletions.
2 changes: 1 addition & 1 deletion docs/quick_tutorial/authentication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Subsequent requests return that cookie and identify the user.
In our template, we fetched the ``logged_in`` value from the view class. We use
this to calculate the logged-in user, if any. In the template we can then
choose to show a login link to anonymous visitors or a logout link to logged-in
users.
users, including their login name.


Extra credit
Expand Down
6 changes: 4 additions & 2 deletions docs/quick_tutorial/authentication/tutorial/home.pt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
<div>
<a tal:condition="view.logged_in is None"
href="${request.application_url}/login">Log In</a>
<a tal:condition="view.logged_in is not None"
href="${request.application_url}/logout">Logout</a>
<span tal:condition="view.logged_in is not None">
<a href="${request.application_url}/logout">Logout</a>
as ${view.logged_in}
</span>
</div>

<h1>Hi ${name}</h1>
Expand Down
2 changes: 0 additions & 2 deletions docs/quick_tutorial/authentication/tutorial/login.pt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<span tal:replace="message"/>

<form action="${url}" method="post">
<input type="hidden" name="came_from"
value="${came_from}"/>
<label for="login">Username</label>
<input type="text" id="login"
name="login"
Expand Down
7 changes: 1 addition & 6 deletions docs/quick_tutorial/authentication/tutorial/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ def hello(self):
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 = ''
Expand All @@ -46,15 +42,14 @@ def login(self):
hashed_pw = USERS.get(login)
if hashed_pw and check_password(password, hashed_pw):
headers = remember(request, login)
return HTTPFound(location=came_from,
return HTTPFound(location=request.route_url("home"),
headers=headers)
message = 'Failed login'

return dict(
name='Login',
message=message,
url=request.application_url + '/login',
came_from=came_from,
login=login,
password=password,
)
Expand Down
14 changes: 11 additions & 3 deletions docs/quick_tutorial/authorization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,17 @@ Of course, this only applies on ``Root``. Some other part of the site (a.k.a.
*context*) might have a different ACL.

If you are not logged in and visit ``/howdy``, you need to get shown the login
screen. How does Pyramid know what is the login page to use? We explicitly told
Pyramid that the ``login`` view should be used by decorating the view with
``@forbidden_view_config``.
screen. How does Pyramid know what is the login page to use? We defined an
explicit "forbidden view", decorating that view with
``@forbidden_view_config``, and then had it store the information about the
route being protected in the request's session, before redirecting to the
login view.

.. note::

We use the session to store the ``came_from`` information, rather than a
hidden form input, in order to avoid trusting user-supplied data (from the
form or query string) when constructing redirect URLs.


Extra credit
Expand Down
9 changes: 7 additions & 2 deletions docs/quick_tutorial/authorization/tutorial/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
from pyramid.config import Configurator
from pyramid.session import SignedCookieSessionFactory

from .security import SecurityPolicy


def main(global_config, **settings):
config = Configurator(settings=settings,
root_factory='.resources.Root')
my_session_factory = SignedCookieSessionFactory('itsaseekreet')
config = Configurator(
settings=settings,
root_factory='.resources.Root',
session_factory=my_session_factory,
)
config.include('pyramid_chameleon')

config.set_security_policy(
Expand Down
6 changes: 4 additions & 2 deletions docs/quick_tutorial/authorization/tutorial/home.pt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
<div>
<a tal:condition="view.logged_in is None"
href="${request.application_url}/login">Log In</a>
<a tal:condition="view.logged_in is not None"
href="${request.application_url}/logout">Logout</a>
<span tal:condition="view.logged_in is not None">
<a href="${request.application_url}/logout">Logout</a>
as ${view.logged_in}
</span>
</div>

<h1>Hi ${name}</h1>
Expand Down
2 changes: 0 additions & 2 deletions docs/quick_tutorial/authorization/tutorial/login.pt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<span tal:replace="message"/>

<form action="${url}" method="post">
<input type="hidden" name="came_from"
value="${came_from}"/>
<label for="login">Username</label>
<input type="text" id="login"
name="login"
Expand Down
43 changes: 34 additions & 9 deletions docs/quick_tutorial/authorization/tutorial/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,58 @@ def home(self):
def hello(self):
return {'name': 'Hello View'}

@forbidden_view_config()
def forbidden(self):
request = self.request
session = request.session
if request.matched_route is not None:
session['came_from'] = {
'route_name': request.matched_route.name,
'route_kwargs': request.matchdict,
}
if request.authenticated_userid is not None:
session['message'] = (
f'User {request.authenticated_userid} is not allowed '
f'to see this resource. Please log in as another user.'
)
else:
if 'came_from' in session:
del session['came_from']

return HTTPFound(request.route_url('login'))

@view_config(route_name='login', renderer='login.pt')
@forbidden_view_config(renderer='login.pt')
def login(self):
request = self.request
session = request.session
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 = ''
came_from = session.get('came_from')
message = session.get('message', '')
login = ''
password = ''

if 'form.submitted' in request.params:
login = request.params['login']
password = request.params['password']
hashed_pw = USERS.get(login)
if hashed_pw and check_password(password, hashed_pw):
headers = remember(request, login)
return HTTPFound(location=came_from,
headers=headers)

if came_from is not None:
return_to = request.route_url(
came_from['route_name'], **came_from['route_kwargs'],
)
else:
return_to = request.route_url('home')

return HTTPFound(location=return_to, headers=headers)

message = 'Failed login'

return dict(
name='Login',
message=message,
url=request.application_url + '/login',
came_from=came_from,
login=login,
password=password,
)
Expand Down
9 changes: 0 additions & 9 deletions docs/quick_tutorial/retail_forms/development.ini

This file was deleted.

20 changes: 0 additions & 20 deletions docs/quick_tutorial/retail_forms/setup.py

This file was deleted.

13 changes: 0 additions & 13 deletions docs/quick_tutorial/retail_forms/tutorial/__init__.py

This file was deleted.

36 changes: 0 additions & 36 deletions docs/quick_tutorial/retail_forms/tutorial/tests.py

This file was deleted.

96 changes: 0 additions & 96 deletions docs/quick_tutorial/retail_forms/tutorial/views.py

This file was deleted.

19 changes: 0 additions & 19 deletions docs/quick_tutorial/retail_forms/tutorial/wiki_view.pt

This file was deleted.

Loading

0 comments on commit ef0f686

Please sign in to comment.