pyramid-fullauth 0.4.0__py3.4.egg

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. EGG-INFO/PKG-INFO +184 -0
  2. EGG-INFO/SOURCES.txt +93 -0
  3. EGG-INFO/dependency_links.txt +1 -0
  4. EGG-INFO/not-zip-safe +1 -0
  5. EGG-INFO/requires.txt +13 -0
  6. EGG-INFO/top_level.txt +2 -0
  7. pyramid_fullauth/__init__.py +106 -0
  8. pyramid_fullauth/__pycache__/__init__.cpython-34.pyc +0 -0
  9. pyramid_fullauth/__pycache__/auth.cpython-34.pyc +0 -0
  10. pyramid_fullauth/__pycache__/events.cpython-34.pyc +0 -0
  11. pyramid_fullauth/__pycache__/exceptions.cpython-34.pyc +0 -0
  12. pyramid_fullauth/__pycache__/request.cpython-34.pyc +0 -0
  13. pyramid_fullauth/__pycache__/tools.cpython-34.pyc +0 -0
  14. pyramid_fullauth/auth.py +67 -0
  15. pyramid_fullauth/config/default.yaml +26 -0
  16. pyramid_fullauth/events.py +281 -0
  17. pyramid_fullauth/exceptions.py +47 -0
  18. pyramid_fullauth/models/__init__.py +190 -0
  19. pyramid_fullauth/models/__pycache__/__init__.cpython-34.pyc +0 -0
  20. pyramid_fullauth/models/extensions/__init__.py +39 -0
  21. pyramid_fullauth/models/extensions/__pycache__/__init__.cpython-34.pyc +0 -0
  22. pyramid_fullauth/models/mixins/__init__.py +9 -0
  23. pyramid_fullauth/models/mixins/__pycache__/__init__.cpython-34.pyc +0 -0
  24. pyramid_fullauth/models/mixins/__pycache__/email.cpython-34.pyc +0 -0
  25. pyramid_fullauth/models/mixins/__pycache__/password.cpython-34.pyc +0 -0
  26. pyramid_fullauth/models/mixins/email.py +128 -0
  27. pyramid_fullauth/models/mixins/password.py +141 -0
  28. pyramid_fullauth/request.py +70 -0
  29. pyramid_fullauth/resources/helpers/social.mako +17 -0
  30. pyramid_fullauth/resources/locale/pyramid_fullauth.pot +216 -0
  31. pyramid_fullauth/resources/templates/403.mako +11 -0
  32. pyramid_fullauth/resources/templates/_form.login.mako +44 -0
  33. pyramid_fullauth/resources/templates/_form.register.mako +47 -0
  34. pyramid_fullauth/resources/templates/_social.login.mako +17 -0
  35. pyramid_fullauth/resources/templates/activate.mako +14 -0
  36. pyramid_fullauth/resources/templates/email_change.mako +33 -0
  37. pyramid_fullauth/resources/templates/layout.mako +13 -0
  38. pyramid_fullauth/resources/templates/login.mako +17 -0
  39. pyramid_fullauth/resources/templates/register.mako +22 -0
  40. pyramid_fullauth/resources/templates/reset.mako +34 -0
  41. pyramid_fullauth/resources/templates/reset.proceed.mako +41 -0
  42. pyramid_fullauth/routing/__init__.py +5 -0
  43. pyramid_fullauth/routing/__pycache__/__init__.cpython-34.pyc +0 -0
  44. pyramid_fullauth/routing/__pycache__/predicates.cpython-34.pyc +0 -0
  45. pyramid_fullauth/routing/predicates.py +86 -0
  46. pyramid_fullauth/tools.py +69 -0
  47. pyramid_fullauth/views/__init__.py +15 -0
  48. pyramid_fullauth/views/__pycache__/__init__.cpython-34.pyc +0 -0
  49. pyramid_fullauth/views/__pycache__/social.cpython-34.pyc +0 -0
  50. pyramid_fullauth/views/basic/__init__.py +5 -0
  51. pyramid_fullauth/views/basic/__pycache__/__init__.cpython-34.pyc +0 -0
  52. pyramid_fullauth/views/basic/__pycache__/activate.cpython-34.pyc +0 -0
  53. pyramid_fullauth/views/basic/__pycache__/forbidden.cpython-34.pyc +0 -0
  54. pyramid_fullauth/views/basic/__pycache__/login.cpython-34.pyc +0 -0
  55. pyramid_fullauth/views/basic/__pycache__/logout.cpython-34.pyc +0 -0
  56. pyramid_fullauth/views/basic/__pycache__/register.cpython-34.pyc +0 -0
  57. pyramid_fullauth/views/basic/activate.py +44 -0
  58. pyramid_fullauth/views/basic/forbidden.py +46 -0
  59. pyramid_fullauth/views/basic/login.py +128 -0
  60. pyramid_fullauth/views/basic/logout.py +28 -0
  61. pyramid_fullauth/views/basic/profile/__init__.py +5 -0
  62. pyramid_fullauth/views/basic/profile/__pycache__/__init__.cpython-34.pyc +0 -0
  63. pyramid_fullauth/views/basic/profile/__pycache__/email.cpython-34.pyc +0 -0
  64. pyramid_fullauth/views/basic/profile/__pycache__/password.cpython-34.pyc +0 -0
  65. pyramid_fullauth/views/basic/profile/email.py +108 -0
  66. pyramid_fullauth/views/basic/profile/password.py +129 -0
  67. pyramid_fullauth/views/basic/register.py +111 -0
  68. pyramid_fullauth/views/social.py +221 -0
  69. tests/__init__.py +1 -0
  70. tests/__pycache__/__init__.cpython-34.pyc +0 -0
  71. tests/__pycache__/conftest.cpython-34.pyc +0 -0
  72. tests/__pycache__/tools.cpython-34.pyc +0 -0
  73. tests/conftest.py +201 -0
  74. tests/tools.py +54 -0
  75. tests/unit/__pycache__/test_default_settings.cpython-34.pyc +0 -0
  76. tests/unit/__pycache__/test_groupfinder.cpython-34.pyc +0 -0
  77. tests/unit/__pycache__/test_social_view.cpython-34.pyc +0 -0
  78. tests/unit/__pycache__/test_tools.cpython-34.pyc +0 -0
  79. tests/unit/__pycache__/test_user_active.cpython-34.pyc +0 -0
  80. tests/unit/__pycache__/test_user_admin.cpython-34.pyc +0 -0
  81. tests/unit/__pycache__/test_user_email.cpython-34.pyc +0 -0
  82. tests/unit/__pycache__/test_user_password.cpython-34.pyc +0 -0
  83. tests/unit/__pycache__/test_user_providers.cpython-34.pyc +0 -0
  84. tests/unit/__pycache__/test_user_repr.cpython-34.pyc +0 -0
  85. tests/unit/__pycache__/test_validators.cpython-34.pyc +0 -0
  86. tests/unit/test_default_settings.py +15 -0
  87. tests/unit/test_groupfinder.py +20 -0
  88. tests/unit/test_social_view.py +69 -0
  89. tests/unit/test_tools.py +24 -0
  90. tests/unit/test_user_active.py +31 -0
  91. tests/unit/test_user_admin.py +61 -0
  92. tests/unit/test_user_email.py +37 -0
  93. tests/unit/test_user_password.py +52 -0
  94. tests/unit/test_user_providers.py +24 -0
  95. tests/unit/test_user_repr.py +29 -0
  96. tests/unit/test_validators.py +44 -0
  97. tests/views/__init__.py +1 -0
  98. tests/views/__pycache__/__init__.cpython-34.pyc +0 -0
  99. tests/views/__pycache__/conftest.cpython-34.pyc +0 -0
  100. tests/views/__pycache__/test_activation.cpython-34.pyc +0 -0
  101. tests/views/__pycache__/test_email.cpython-34.pyc +0 -0
  102. tests/views/__pycache__/test_events.cpython-34.pyc +0 -0
  103. tests/views/__pycache__/test_login.cpython-34.pyc +0 -0
  104. tests/views/__pycache__/test_login_social.cpython-34.pyc +0 -0
  105. tests/views/__pycache__/test_logout.cpython-34.pyc +0 -0
  106. tests/views/__pycache__/test_register.cpython-34.pyc +0 -0
  107. tests/views/__pycache__/test_reset.cpython-34.pyc +0 -0
  108. tests/views/conftest.py +20 -0
  109. tests/views/test_activation.py +86 -0
  110. tests/views/test_email.py +175 -0
  111. tests/views/test_events.py +558 -0
  112. tests/views/test_login.py +172 -0
  113. tests/views/test_login_social.py +289 -0
  114. tests/views/test_logout.py +42 -0
  115. tests/views/test_register.py +138 -0
  116. tests/views/test_reset.py +105 -0
@@ -0,0 +1,17 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <%namespace name="social" file="../helpers/social.mako" import="social_auth_uri"/>
9
+ <h1>${_('Social login', domain='pyramid_fullauth')}</h1>
10
+ % if 'social' in request.registry['config'].fullauth:
11
+ % if 'facebook' in request.registry['config'].fullauth.social:
12
+ <a href="${social.social_auth_uri('facebook', scope=request.registry['config'].fullauth.social.facebook.scope)}">${_('Connect with facebook', domain='pyramid_fullauth')}</a>
13
+ % endif
14
+ % if 'twitter' in request.registry['config'].fullauth.social:
15
+ <a href="${social.social_auth_uri('twitter')}">${_('Connect with twitter', domain='pyramid_fullauth')}</a>
16
+ % endif
17
+ % endif
@@ -0,0 +1,14 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <%inherit file="pyramid_fullauth:resources/templates/layout.mako" />
9
+ % if not status:
10
+ <h1>${_('Invalid activation code', domain='pyramid_fullauth')}</h1>
11
+ % else:
12
+ <h1>${_('Thank you for activating your account!', domain='pyramid_fullauth')}</h1>
13
+ <p>${_('And welcome to our site!', domain='pyramid_fullauth')}</p>
14
+ % endif
@@ -0,0 +1,33 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <%inherit file="pyramid_fullauth:resources/templates/layout.mako" />
9
+
10
+ <h1>${_('Change your email', domain='pyramid_fullauth')}</h1>
11
+ <div class="row-fluid">
12
+ <div class="span2"></div>
13
+ <div class="span8">
14
+ % if not status:
15
+ <div class="alert alert-error">${_('Error!', domain='pyramid_fullauth')} ${msg}</div>
16
+ % endif
17
+ <form class="form-horizontal" name="reset_password" method="POST" action="${request.current_route_path()}">
18
+ <fieldset>
19
+ <div class="control-group">
20
+ <label class="control-label" for="reset[email]">${_('Your e-mail address', domain='pyramid_fullauth')}:</label>
21
+ <div class="controls">
22
+ <input type="email" placeholder="username@hostname.com" name="email" id="change[email]"/>
23
+ <input type="hidden" name="csrf_token" value="${csrf_token}" />
24
+ </div>
25
+ </div>
26
+ <div class="form-actions">
27
+ <button type="submit" class="btn btn-large">${_('Change email', domain='pyramid_fullauth')}</button>
28
+ </div>
29
+ </fieldset>
30
+ </form>
31
+ </div>
32
+ <div class="span2"></div>
33
+ </div>
@@ -0,0 +1,13 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <html>
9
+ <body>
10
+ <h1>${_('Welcome, to pyramid_fullauth!', domain='pyramid_fullauth')}</h1>
11
+ ${next.body()}
12
+ </body>
13
+ </html>
@@ -0,0 +1,17 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <% import sys %>
3
+ <%doc>
4
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
5
+
6
+ This module is part of pyramid_fullauth and is released under
7
+ the MIT License (MIT): http://opensource.org/licenses/MIT
8
+ </%doc>
9
+ <%inherit file="pyramid_fullauth:resources/templates/layout.mako" />
10
+ <h1>${_('Please, log in', domain='pyramid_fullauth')}:</h1>
11
+ % if not status:
12
+ <div class="alert alert-error">${_('Error!', domain='pyramid_fullauth')} ${msg}</div>
13
+ % endif
14
+ <%include file="_form.login.mako"/>
15
+ % if sys.version_info.major == 2:
16
+ <%include file="_social.login.mako"/>
17
+ % endif
@@ -0,0 +1,22 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <%inherit file="pyramid_fullauth:resources/templates/layout.mako" />
9
+ <h1>${_('Please, register', domain='pyramid_fullauth')}:</h1>
10
+ % if errors:
11
+ <div class="alert alert-error">
12
+ <button type="button" class="close" data-dismiss="alert">x</button>
13
+ <strong>${_('Error!', domain='pyramid_fullauth')}</strong> ${msg}
14
+ </div>
15
+ % elif not request.method == 'GET':
16
+ <div class="alert alert-success">
17
+ <button type="button" class="close" data-dismiss="alert">x</button>
18
+ <strong>${_('Success!', domain='pyramid_fullauth')}</strong> ${_('You have sucessfully registered', domain='pyramid_fullauth')}
19
+ </div>
20
+ % endif
21
+ <%include file="_form.register.mako"/>
22
+ <%include file="_social.login.mako"/>
@@ -0,0 +1,34 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <%inherit file="pyramid_fullauth:resources/templates/layout.mako" />
9
+
10
+ <h1>${_('Recover your password', domain='pyramid_fullauth')}</h1>
11
+ <div class="row-fluid">
12
+ <div class="span2"></div>
13
+ <div class="span8">
14
+ % if not status:
15
+ <div class="alert alert-error">${_('Error!', domain='pyramid_fullauth')} ${msg}</div>
16
+ % endif
17
+ <form class="form-horizontal" name="reset_password" method="POST" action="${request.current_route_path()}">
18
+ <fieldset>
19
+ <div class="control-group">
20
+ <label class="control-label" for="reset[email]">${_('Your e-mail address', domain='pyramid_fullauth')}:</label>
21
+ <div class="controls">
22
+ <input type="email" placeholder="username@hostname.com" name="email" id="reset[email]"/>
23
+ <input type="hidden" name="csrf_token" value="${csrf_token}" />
24
+ </div>
25
+ </div>
26
+ <div class="form-actions">
27
+ <button type="submit" class="btn btn-large">${_('Reset Password', domain='pyramid_fullauth')}</button>
28
+ </div>
29
+ </fieldset>
30
+ </form>
31
+ </div>
32
+ <div class="span2"></div>
33
+ </div>
34
+
@@ -0,0 +1,41 @@
1
+ ## -*- coding: utf-8 -*-
2
+ <%doc>
3
+ Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
4
+
5
+ This module is part of pyramid_fullauth and is released under
6
+ the MIT License (MIT): http://opensource.org/licenses/MIT
7
+ </%doc>
8
+ <%inherit file="pyramid_fullauth:resources/templates/layout.mako" />
9
+
10
+ <h1>${_('Recover your password - choose new password', domain='pyramid_fullauth')}</h1>
11
+ <div class="row-fluid">
12
+ <div class="span8">
13
+ % if not status:
14
+ <div class="alert alert-error">${_('Error!', domain='pyramid_fullauth')} ${msg}</div>
15
+ % endif
16
+ <form class="form-horizontal" id="reset_password" name="reset_password" method="POST" action="${request.current_route_path()}">
17
+ <input type="hidden" name="csrf_token" value="${csrf_token}" />
18
+ <fieldset>
19
+ <div class="control-group">
20
+ <label class="control-label" for="password">${_('Password', domain='pyramid_fullauth')}:</label>
21
+ <div class="controls">
22
+ <input type="password" id="password" name="password" placeholder="minimum 6 characters"/>
23
+ <span class="help-inline" id="password_status"></span>
24
+ </div>
25
+ </div>
26
+ <div class="control-group">
27
+ <label class="control-label" for="confirm_password">${_('Confirm password', domain='pyramid_fullauth')}:</label>
28
+ <div class="controls">
29
+ <input type="password" name="confirm_password" id="confirm_password"/>
30
+ <span class="help-inline" id="confirm_password_status"></span>
31
+ </div>
32
+ </div>
33
+ <div class="form-actions">
34
+ <button type="submit" class="btn btn-large">${_('Reset Password', domain='pyramid_fullauth')}</button>
35
+ </div>
36
+ </fieldset>
37
+ </form>
38
+ </div>
39
+ <div class="span2"></div>
40
+ </div>
41
+
@@ -0,0 +1,5 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Routing module."""
@@ -0,0 +1,86 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Routing predicate definitions."""
6
+
7
+ from sqlalchemy.orm.exc import NoResultFound
8
+ from pyramid.config.predicates import CheckCSRFTokenPredicate
9
+ from pyramid.httpexceptions import HTTPUnauthorized
10
+ import pyramid_basemodel
11
+
12
+ from pyramid_fullauth.models import User
13
+
14
+
15
+ def reset_hash(info, request):
16
+ """
17
+ Check whether reset hash is correct.
18
+
19
+ :param dict info: pyramid info dict with path fragments and info
20
+ :param pyramid.request.Request request: request object
21
+
22
+ :returns: whether reset hash exists or not
23
+ :rtype: bool
24
+
25
+ """
26
+ reset_hash = info['match'].get('hash', None)
27
+ if reset_hash:
28
+ try:
29
+ info['match']['user'] = pyramid_basemodel.Session.query(User).filter(User.reset_key == reset_hash).one()
30
+ return True
31
+ except NoResultFound:
32
+ pass
33
+ return False
34
+
35
+
36
+ def change_email_hash(info, request):
37
+ """
38
+ Check whether change email hash is correct.
39
+
40
+ :param dict info: pyramid info dict with path fragments and info
41
+ :param pyramid.request.Request request: request object
42
+
43
+ :returns: whether change email hash exists or not
44
+ :rtype: bool
45
+
46
+ """
47
+ change_email_hash = info['match'].get('hash', None)
48
+ if change_email_hash:
49
+ try:
50
+ info['match']['user'] = pyramid_basemodel.Session.query(User).filter(User.email_change_key == change_email_hash).one()
51
+ return True
52
+ except NoResultFound:
53
+ pass
54
+ return False
55
+
56
+
57
+ class CSRFCheckPredicate(CheckCSRFTokenPredicate):
58
+
59
+ """
60
+ Run csrf check dependant on configuration.
61
+
62
+ .. note::
63
+
64
+ Raises HTTPUnauthorized exception if check fails.
65
+
66
+ :raises: pyramid.httpexceptions.HTTPUnauthorized
67
+
68
+ :returns: True if check succeeds or turned off.
69
+ :rtype: bool
70
+
71
+ """
72
+
73
+ def __call__(self, context, request):
74
+ """
75
+ Run predicate check.
76
+
77
+ :param context:
78
+ :param pyramid.request.Request request:
79
+
80
+ """
81
+ if request.registry['config'].fullauth.check_csrf:
82
+ result = CheckCSRFTokenPredicate.__call__(self, context, request)
83
+ if not result:
84
+ raise HTTPUnauthorized
85
+
86
+ return True
@@ -0,0 +1,69 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Additional tools used in pyramid_fullauth."""
6
+
7
+ import string
8
+ from random import choice
9
+
10
+ from pyramid.compat import text_type
11
+
12
+ from pyramid_fullauth.exceptions import (
13
+ EmptyError, ShortPasswordError, PasswordConfirmMismatchError
14
+ )
15
+
16
+
17
+ def password_generator(length, chars=(string.ascii_letters + string.digits + string.punctuation)):
18
+ """
19
+ Generate random password.
20
+
21
+ .. warning::
22
+
23
+ TODO: tests!
24
+
25
+ :param int length: length of a password to Generates
26
+ :param list chars: list of characters from which to choose
27
+ :returns: password
28
+ :rtype: str
29
+ """
30
+ return text_type(''.join([choice(chars) for i in range(length)]))
31
+
32
+
33
+ def validate_passsword(request, password, user=None):
34
+ """
35
+ Validate password properly.
36
+
37
+ .. note::
38
+
39
+ If no user provided, password is just validated
40
+
41
+ :param pyramid.request.Request request: request object
42
+ :param str password: password to be set
43
+ :param pyramid_fullauth.models.User user: user object
44
+
45
+ :raises: pyramid_fullauth.exceptions.ValidateError
46
+ """
47
+ password_config = request.registry['config'].fullauth.register.password
48
+ if not password:
49
+ raise EmptyError(
50
+ request._('Please enter your password',
51
+ domain='pyramid_fullauth'))
52
+
53
+ if password_config['length_min'] and\
54
+ len(password) < password_config['length_min']:
55
+ raise ShortPasswordError(
56
+ request._('Password is too short',
57
+ domain='pyramid_fullauth'))
58
+
59
+ # here if password doesn't match
60
+ if password_config['confirm']:
61
+ confirm_password = request.POST.get('confirm_password', text_type(''))
62
+ if password != confirm_password:
63
+ raise PasswordConfirmMismatchError(
64
+ request._('password-mismatch',
65
+ default='Passwords don\'t match',
66
+ domain='pyramid_fullauth'))
67
+
68
+ if user:
69
+ user.password = password
@@ -0,0 +1,15 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Views submodule."""
6
+
7
+
8
+ class BaseView(object):
9
+
10
+ """basic view class."""
11
+
12
+ def __init__(self, request):
13
+ """Common init for views."""
14
+ self.request = request
15
+ self.config = request.registry['config'].fullauth
@@ -0,0 +1,5 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Basic views."""
@@ -0,0 +1,44 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Registration related views."""
6
+
7
+ from pyramid.view import view_config
8
+ from pyramid.httpexceptions import HTTPRedirection
9
+ from pyramid.security import NO_PERMISSION_REQUIRED
10
+
11
+ from sqlalchemy.orm.exc import NoResultFound
12
+ import pyramid_basemodel
13
+
14
+ from pyramid_fullauth.views import BaseView
15
+ from pyramid_fullauth.models import User
16
+ from pyramid_fullauth.events import AfterActivate
17
+
18
+
19
+ @view_config(route_name='register:activate', permission=NO_PERMISSION_REQUIRED,
20
+ renderer="pyramid_fullauth:resources/templates/activate.mako")
21
+ class ActivateView(BaseView):
22
+
23
+ """Activate account views."""
24
+
25
+ def __call__(self):
26
+ """Process account activation."""
27
+ activate_hash = self.request.matchdict.get('hash')
28
+ user = None
29
+ response = {}
30
+ response['status'] = True
31
+ if activate_hash:
32
+ try:
33
+ user = pyramid_basemodel.Session.query(User).filter(User.activate_key == activate_hash).one()
34
+ if not user.is_active:
35
+ user.is_active = True
36
+ except NoResultFound:
37
+ response['status'] = False
38
+ try:
39
+ self.request.registry.notify(AfterActivate(self.request, user))
40
+ except HTTPRedirection as e:
41
+ # it's a redirect, let's follow it!
42
+ return e
43
+
44
+ return response
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Forbidden views."""
6
+
7
+ from pyramid.view import forbidden_view_config
8
+ from pyramid.httpexceptions import HTTPFound
9
+
10
+ from pyramid_fullauth.views import BaseView
11
+
12
+
13
+ class ForbiddenViews(BaseView):
14
+
15
+ """Forbidden related views."""
16
+
17
+ def __init__(self, request):
18
+ """Set all responses status to 403 by default."""
19
+ super(ForbiddenViews, self).__init__(request)
20
+ self.request.response.status_code = 403
21
+
22
+ @forbidden_view_config(renderer='pyramid_fullauth:resources/templates/403.mako')
23
+ def forbidden(self):
24
+ """Forbidden page view."""
25
+ # do not allow a user to login if they are already logged in
26
+ if self.request.authenticated_userid:
27
+ return {}
28
+
29
+ loc = self.request.route_path('login', _query=(('after', self.request.path),))
30
+ return HTTPFound(location=loc)
31
+
32
+ @forbidden_view_config(xhr=True, renderer='json')
33
+ def forbidden_json(self):
34
+ """Forbidden xhr response."""
35
+ # do not allow a user to login if they are already logged in
36
+ if self.request.authenticated_userid:
37
+ return {'status': False, 'msg':
38
+ self.request._('forbidden-notallowed',
39
+ default='You are not allowed to use this function',
40
+ domain='pyramid_fullauth')}
41
+
42
+ return {'status': False,
43
+ 'msg': self.request._('forbidden-login',
44
+ default='You have to be logged in to use this function',
45
+ domain='pyramid_fullauth'),
46
+ 'login_url': self.request.route_path('login')}
@@ -0,0 +1,128 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """Authorisation related views."""
6
+
7
+ from pyramid.view import view_config
8
+ from pyramid.view import view_defaults
9
+ from pyramid.httpexceptions import HTTPSeeOther, HTTPRedirection
10
+ from pyramid.security import NO_PERMISSION_REQUIRED
11
+
12
+ from sqlalchemy.orm.exc import NoResultFound
13
+ from pyramid.compat import text_type
14
+ import pyramid_basemodel
15
+
16
+ from pyramid_fullauth.views import BaseView
17
+ from pyramid_fullauth.models import User
18
+ from pyramid_fullauth.events import BeforeLogIn
19
+ from pyramid_fullauth.events import AfterLogIn
20
+ from pyramid_fullauth.events import AlreadyLoggedIn
21
+
22
+
23
+ @view_defaults(route_name='login', permission=NO_PERMISSION_REQUIRED,
24
+ renderer='pyramid_fullauth:resources/templates/login.mako')
25
+ class BaseLoginView(BaseView):
26
+
27
+ """Basic logic for login views."""
28
+
29
+ def __init__(self, request):
30
+ """Prepare login views."""
31
+ super(BaseLoginView, self).__init__(request)
32
+
33
+ self.response = {
34
+ 'status': False,
35
+ 'msg': self.request._('Login error', domain='pyramid_fullauth'),
36
+ 'after': self.request.params.get(
37
+ 'after', self.request.referer or '/'),
38
+ 'csrf_token': self.request.session.get_csrf_token()
39
+ }
40
+
41
+ def _redirect_authenticated_user(self):
42
+ """Redirect already logged in user away from login page."""
43
+ redirect = HTTPSeeOther(location=self.response['after'])
44
+ try:
45
+ self.request.registry.notify(AlreadyLoggedIn(self.request))
46
+ except HTTPRedirection as e_redirect:
47
+ redirect = e_redirect
48
+
49
+ if self.request.is_xhr:
50
+ self.response['status'] = True
51
+ self.response['msg'] = self.request._(
52
+ 'Already logged in!',
53
+ domain='pyramid_fullauth')
54
+ self.response['after'] = redirect.location
55
+ return self.response
56
+ else:
57
+ return redirect
58
+
59
+
60
+ @view_config(request_method='GET')
61
+ class LoginView(BaseLoginView):
62
+
63
+ """Login view."""
64
+
65
+ def __call__(self):
66
+ """Display login page."""
67
+ if self.request.authenticated_userid:
68
+ return self._redirect_authenticated_user()
69
+
70
+ self.request.registry.notify(BeforeLogIn(self.request, None))
71
+
72
+ self.response['status'] = True
73
+ del self.response['msg']
74
+ return self.response
75
+
76
+
77
+ @view_config(request_method='POST', check_csrf=True)
78
+ @view_config(request_method='POST', check_csrf=True, xhr=True, renderer="json")
79
+ class LoginViewPost(BaseLoginView):
80
+
81
+ """Login view POST method."""
82
+
83
+ def __call__(self):
84
+ """Login action."""
85
+ if self.request.authenticated_userid:
86
+ return self._redirect_authenticated_user()
87
+
88
+ email = self.request.POST.get('email', '')
89
+ password = self.request.POST.get('password', '')
90
+ try:
91
+ user = pyramid_basemodel.Session.query(User).filter(User.email == email).one()
92
+ except NoResultFound:
93
+ self.request.registry.notify(BeforeLogIn(self.request, None))
94
+
95
+ self.response['msg'] = self.request._('Wrong e-mail or password.',
96
+ domain='pyramid_fullauth')
97
+ return self.response
98
+
99
+ try:
100
+ self.request.registry.notify(BeforeLogIn(self.request, user))
101
+ except AttributeError as e:
102
+ self.response['msg'] = text_type(e)
103
+ return self.response
104
+
105
+ if user.check_password(password):
106
+
107
+ login_kwargs = {'remember_me': self.request.POST.get('remember')}
108
+ try:
109
+ # if remember in POST set cookie timeout to one month
110
+ self.request.registry.notify(AfterLogIn(self.request, user))
111
+ except AttributeError as e:
112
+ self.response['msg'] = text_type(e)
113
+ return self.response
114
+ except HTTPRedirection as redirect:
115
+ login_kwargs['location'] = redirect.location
116
+
117
+ redirect = self.request.login_perform(user, **login_kwargs)
118
+ if self.request.is_xhr:
119
+ self.response['status'] = True
120
+ del self.response['msg']
121
+ self.response['after'] = redirect.location
122
+ return self.response
123
+ else:
124
+ return redirect
125
+ else:
126
+ self.response['msg'] = self.request._('Wrong e-mail or password.',
127
+ domain='pyramid_fullauth')
128
+ return self.response
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2013 - 2014 by pyramid_fullauth authors and contributors <see AUTHORS file>
2
+ #
3
+ # This module is part of pyramid_fullauth and is released under
4
+ # the MIT License (MIT): http://opensource.org/licenses/MIT
5
+ """De-authentication related view."""
6
+
7
+ from pyramid.view import view_config
8
+ from pyramid.httpexceptions import HTTPSeeOther
9
+ from pyramid.security import NO_PERMISSION_REQUIRED
10
+
11
+ from pyramid_fullauth.views import BaseView
12
+
13
+
14
+ @view_config(route_name='logout', permission=NO_PERMISSION_REQUIRED)
15
+ class LogoutView(BaseView):
16
+
17
+ """Logout view."""
18
+
19
+ def __call__(self):
20
+ """Logout action."""
21
+ location = '/'
22
+ if self.config.redirects.logout:
23
+ location = self.request.route_path(self.config.redirects.logout)
24
+ # forget headers
25
+ self.request.logout()
26
+
27
+ return HTTPSeeOther(location=location,
28
+ headers=self.request.response.headers)