Browse Source

added resources for tokens

master
Holger Frey 7 years ago
parent
commit
9def414339
  1. 75
      ordr2/resources/account.py

75
ordr2/resources/account.py

@ -1,22 +1,67 @@ @@ -1,22 +1,67 @@
''' Resources for account registraion and settings '''
from datetime import datetime
from pyramid.security import Allow, Authenticated, Everyone, Deny, DENY_ALL
from ordr2.models.account import Token, TokenSubject
from ordr2.resources.base import BaseResource
class RegistrationToken(BaseResource):
''' representing :class:`ordr2.models.account.Token` for registration '''
def __acl__(self):
''' access controll list for the resource '''
return [
(Deny, Authenticated, 'register'),
(Allow, Everyone, 'register'),
DENY_ALL
]
class EmailVerificationToken(BaseResource):
''' representing :class:`ordr2.models.account.Token` for email change '''
def __acl__(self):
''' access controll list for the resource
a logged in user might only access his own tokens
'''
# self.model is a :class:`ordr2.models.account.Token` instance
return [
(Allow, self.model.user.principal, 'settings'),
DENY_ALL
]
class ForgottenPasswordToken(BaseResource):
''' representing :class:`ordr2.models.account.Token` for password reset '''
def __acl__(self):
''' access controll list for the resource '''
return [
(Allow, Everyone, 'reset password'),
DENY_ALL
]
class AccountResource(BaseResource):
''' Resouce class for account registration and settings '''
#: name of the main navigation section for template highlighting
nav_section = 'account'
#: mapping token subjects to token resouce classes
token_resources = {
TokenSubject.USER_REGISTRATION: RegistrationToken,
TokenSubject.CHANGE_EMAIL: EmailVerificationToken,
TokenSubject.RESET_PASSWORD: ForgottenPasswordToken
}
def __init__(self, name, parent, model=None):
''' Create a base resource '''
super().__init__(name, parent)
# the current model depends is the current logged in user or None
self.model = self.request.user
# the current model is the current logged in user or None
super().__init__(name, parent, self.request.user)
def __acl__(self):
''' access controll list for the resource
@ -31,6 +76,28 @@ class AccountResource(BaseResource): @@ -31,6 +76,28 @@ class AccountResource(BaseResource):
(Allow, Everyone, 'logout'),
(Deny, Authenticated, 'register'),
(Allow, Everyone, 'register'),
(Allow, Everyone, 'reset password'),
(Allow, Authenticated, 'settings'),
DENY_ALL
]
def __getitem__(self, key):
''' provides the dict like interface to access child resources
:param str key:
token hash or path segment for a child resource
:rtype:
subclass of ordr2.resources.base.BaseResource
:raises:
KeyError if token hash or path segment is not found
'''
token = self.request.dbsession.query(Token).filter_by(hash=key).first()
if token is None:
# no token found, search for child node
return super().__getitem__(key)
elif token.expires < datetime.utcnow():
# token has expired, delete it
self.request.dbsession.delete(token)
raise KeyError(f'Token {key} has expired on {token.expires}')
resource_class = self.token_resources[token.subject]
return resource_class(key, self, model=token)