Browse Source

passwort reset links are working

php2python
Holger Frey 7 years ago
parent
commit
30df8627db
  1. 2
      ordr2/resources/__init__.py
  2. 38
      ordr2/resources/account.py
  3. 27
      ordr2/schemas/account.py
  4. 24
      ordr2/templates/account/password_reset.jinja2
  5. 55
      ordr2/views/account.py

2
ordr2/resources/__init__.py

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
from pyramid.security import Allow, Everyone
from .account import Account
from .account import Account, PasswordResetAccount
from .admin import Admin, UserList, UserAccount
from .base import BaseResource

38
ordr2/resources/account.py

@ -1,10 +1,44 @@ @@ -1,10 +1,44 @@
from pyramid.security import Allow, Authenticated, Deny, Everyone
from pyramid.security import Allow, Authenticated, Deny, DENY_ALL, Everyone
from ordr2.models import User
from .base import BaseResource
class PasswordResetAccount(BaseResource):
def __acl__(self):
return [
(Allow, Everyone, 'reset'),
DENY_ALL
]
class PasswordReset(BaseResource):
def __acl__(self):
return [
(Allow, Everyone, 'reset'),
DENY_ALL
]
def __getitem__(self, key):
key = key.strip()
if key:
account = self.request.dbsession.\
query(User).\
filter_by(password_reset=key).\
first()
if account:
return PasswordResetAccount(key, self, account)
raise KeyError
class Account(BaseResource):
nodes = {'reset': PasswordReset}
def __init__(self, name, parent):
super().__init__(name, parent)
self.model = self.request.user
@ -17,4 +51,6 @@ class Account(BaseResource): @@ -17,4 +51,6 @@ class Account(BaseResource):
(Deny, Authenticated, 'register'),
(Allow, Everyone, 'register'),
(Allow, Authenticated, 'settings'),
(Allow, Everyone, 'reset'),
DENY_ALL
]

27
ordr2/schemas/account.py

@ -105,15 +105,6 @@ class ChangePasswordSchema(CSRFSchema): @@ -105,15 +105,6 @@ class ChangePasswordSchema(CSRFSchema):
missing=''
)
@classmethod
def as_form(cls, request, **override):
settings = {
'buttons': ('Change Password', 'Cancel'),
'css_class': 'form-horizontal'
}
settings.update(override)
return super().as_form(request, **settings)
class ConfirmSettingsSchema(CSRFSchema):
''' confirm changes with current password '''
@ -148,3 +139,21 @@ class SettingsSchema(CSRFSchema): @@ -148,3 +139,21 @@ class SettingsSchema(CSRFSchema):
template='textinput_disabled.pt'
)
return form
class ResetPasswordSchema(CSRFSchema):
''' reset password of an account '''
new_password = colander.SchemaNode(
colander.String(),
widget=deform.widget.CheckedPasswordWidget()
)
@classmethod
def as_form(cls, request, **override):
settings = {
'buttons': ('Change Password', 'Cancel'),
'css_class': 'form-horizontal'
}
settings.update(override)
return super().as_form(request, **settings)

24
ordr2/templates/account/password_reset.jinja2

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
{% extends "ordr2:templates/layout.jinja2" %}
{% import 'ordr2:templates/macros.jinja2' as macros with context %}
{% block subtitle %} Account | Reset Password {% endblock subtitle %}
{% block content %}
<div class="content controls">
<div class="container-fluid">
<div class="row-fluid">
<div class="page-controls">
<h1>Reset your Password</h1>
</div>
</div>
<div class="row">
<div class="span8">
{{ macros.flash_messages() }}
{{form.render()|safe}}
</div>
</div>
</div>
</div>
{% endblock content %}

55
ordr2/views/account.py

@ -7,7 +7,11 @@ from pyramid.view import view_config @@ -7,7 +7,11 @@ from pyramid.view import view_config
from ordr2.events import UserLogIn
from ordr2.models import User, Role
from ordr2.schemas.account import RegistrationSchema, SettingsSchema
from ordr2.schemas.account import (
ResetPasswordSchema,
RegistrationSchema,
SettingsSchema
)
# user log in and log out
@ -185,6 +189,9 @@ def settings_form(context, request): @@ -185,6 +189,9 @@ def settings_form(context, request):
def settings_form_processing(context, request):
''' display the user settings form '''
if 'Cancel' in request.POST:
return HTTPFound(request.resource_url(request.root))
form = SettingsSchema.as_form(request)
data = request.POST.items()
try:
@ -207,3 +214,49 @@ def settings_form_processing(context, request): @@ -207,3 +214,49 @@ def settings_form_processing(context, request):
request.flash('success', 'Your account information has been updated.')
return {'form': form}
# passwort reset links
@view_config(
context='ordr2:resources.PasswordResetAccount',
permission='reset',
request_method='GET',
renderer='ordr2:templates/account/password_reset.jinja2'
)
def reset_password_form(context, request):
''' display the password reset form '''
form = ResetPasswordSchema.as_form(request)
return {'form': form}
@view_config(
context='ordr2:resources.PasswordResetAccount',
permission='reset',
request_method='POST',
renderer='ordr2:templates/account/password_reset.jinja2'
)
def reset_password_form_processing(context, request):
''' process the password reset form '''
if 'Cancel' in request.POST:
return HTTPFound(request.resource_url(request.root))
form = ResetPasswordSchema.as_form(request)
data = request.POST.items()
try:
appstruct = form.validate(data)
except deform.ValidationFailure as e:
return {'form': form}
context.model.set_password(appstruct['new_password'])
context.model.password_reset = ''
request.flash(
'success',
'Password reset successful',
'Please Log In with your new password',
)
return HTTPFound(request.resource_url(request.root, 'account', 'login'))