WuttaWeb 0.1.0__tar.gz → 0.3.0__tar.gz
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.
- wuttaweb-0.3.0/CHANGELOG.md +38 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/PKG-INFO +10 -9
- wuttaweb-0.1.0/README.rst → wuttaweb-0.3.0/README.md +1 -3
- wuttaweb-0.3.0/docs/api/wuttaweb/auth.rst +6 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/db.rst +6 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/forms.base.rst +6 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/forms.rst +6 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/handler.rst +6 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/index.rst +8 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/menus.rst +6 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/views.auth.rst +6 -0
- wuttaweb-0.3.0/docs/api/wuttaweb/views.essential.rst +6 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/conf.py +3 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/index.rst +5 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/pyproject.toml +13 -6
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/app.py +45 -3
- wuttaweb-0.3.0/src/wuttaweb/auth.py +150 -0
- wuttaweb-0.3.0/src/wuttaweb/db.py +66 -0
- wuttaweb-0.3.0/src/wuttaweb/forms/__init__.py +31 -0
- wuttaweb-0.3.0/src/wuttaweb/forms/base.py +476 -0
- wuttaweb-0.3.0/src/wuttaweb/handler.py +57 -0
- wuttaweb-0.3.0/src/wuttaweb/menus.py +307 -0
- wuttaweb-0.3.0/src/wuttaweb/static/img/favicon.ico +0 -0
- wuttaweb-0.3.0/src/wuttaweb/static/img/logo.png +0 -0
- wuttaweb-0.3.0/src/wuttaweb/subscribers.py +263 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/auth/change_password.mako +7 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/auth/login.mako +48 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/templates/base.mako +56 -4
- wuttaweb-0.3.0/src/wuttaweb/templates/base_meta.mako +25 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/deform/checked_password.pt +13 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/deform/password.pt +8 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/deform/textinput.pt +7 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/form.mako +24 -0
- wuttaweb-0.3.0/src/wuttaweb/templates/forms/vue_template.mako +58 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/templates/home.mako +3 -5
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/util.py +22 -1
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/views/__init__.py +1 -1
- wuttaweb-0.3.0/src/wuttaweb/views/auth.py +288 -0
- wuttaweb-0.3.0/src/wuttaweb/views/base.py +91 -0
- wuttaweb-0.1.0/src/wuttaweb/views/base.py → wuttaweb-0.3.0/src/wuttaweb/views/essential.py +13 -21
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tasks.py +1 -1
- wuttaweb-0.3.0/tests/forms/test_base.py +271 -0
- wuttaweb-0.3.0/tests/test_auth.py +145 -0
- wuttaweb-0.3.0/tests/test_handler.py +20 -0
- wuttaweb-0.3.0/tests/test_menus.py +321 -0
- wuttaweb-0.3.0/tests/test_subscribers.py +255 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/test_util.py +27 -0
- wuttaweb-0.3.0/tests/views/__init__.py +0 -0
- wuttaweb-0.3.0/tests/views/test_auth.py +190 -0
- wuttaweb-0.3.0/tests/views/test_base.py +37 -0
- wuttaweb-0.1.0/CHANGELOG.md +0 -12
- wuttaweb-0.1.0/src/wuttaweb/subscribers.py +0 -140
- wuttaweb-0.1.0/src/wuttaweb/templates/base_meta.mako +0 -21
- wuttaweb-0.1.0/tests/test_subscribers.py +0 -100
- wuttaweb-0.1.0/tests/views/test_base.py +0 -21
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/.gitignore +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/COPYING.txt +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/Makefile +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/_static/.keepme +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/index.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/app.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/helpers.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/static.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/subscribers.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/util.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/views.base.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/views.common.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/api/wuttaweb/views.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/glossary.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/make.bat +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/docs/narr/index.rst +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/__init__.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/_version.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/helpers.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/static/__init__.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/static/img/testing.png +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/templates/page.mako +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/src/wuttaweb/views/common.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/__init__.py +0 -0
- {wuttaweb-0.1.0/tests/views → wuttaweb-0.3.0/tests/forms}/__init__.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/test_app.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/test_helpers.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/test_static.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/views/test___init__.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tests/views/test_common.py +0 -0
- {wuttaweb-0.1.0 → wuttaweb-0.3.0}/tox.ini +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
# Changelog
|
|
3
|
+
All notable changes to wuttaweb will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## v0.3.0 (2024-08-05)
|
|
9
|
+
|
|
10
|
+
### Feat
|
|
11
|
+
|
|
12
|
+
- add support for admin user to become / stop being root
|
|
13
|
+
- add view to change current user password
|
|
14
|
+
- add basic logo, favicon images
|
|
15
|
+
- add auth views, for login/logout
|
|
16
|
+
- add custom security policy, login/logout for pyramid
|
|
17
|
+
- add `wuttaweb.views.essential` module
|
|
18
|
+
- add initial/basic forms support
|
|
19
|
+
- add `wuttaweb.db` module, with `Session`
|
|
20
|
+
- add `util.get_form_data()` convenience function
|
|
21
|
+
|
|
22
|
+
### Fix
|
|
23
|
+
|
|
24
|
+
- allow custom user getter for `new_request_set_user()` hook
|
|
25
|
+
|
|
26
|
+
## v0.2.0 (2024-07-14)
|
|
27
|
+
|
|
28
|
+
### Feat
|
|
29
|
+
|
|
30
|
+
- add basic support for menu handler
|
|
31
|
+
|
|
32
|
+
- add "web handler" feature; it must get the menu handler
|
|
33
|
+
|
|
34
|
+
## v0.1.0 (2024-07-12)
|
|
35
|
+
|
|
36
|
+
### Feat
|
|
37
|
+
|
|
38
|
+
- basic support for WSGI app, views, templates
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: WuttaWeb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Web App for Wutta Framework
|
|
5
|
-
Project-URL: Homepage, https://
|
|
6
|
-
Project-URL: Repository, https://
|
|
7
|
-
Project-URL: Changelog, https://
|
|
5
|
+
Project-URL: Homepage, https://wuttaproject.org/
|
|
6
|
+
Project-URL: Repository, https://forgejo.wuttaproject.org/wutta/wuttaweb
|
|
7
|
+
Project-URL: Changelog, https://forgejo.wuttaproject.org/wutta/wuttaweb/src/branch/master/CHANGELOG.md
|
|
8
8
|
Author-email: Lance Edgar <lance@edbob.org>
|
|
9
9
|
License: GNU GPL v3+
|
|
10
10
|
License-File: COPYING.txt
|
|
@@ -25,23 +25,24 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
25
25
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
26
26
|
Requires-Python: >=3.8
|
|
27
27
|
Requires-Dist: pyramid-beaker
|
|
28
|
+
Requires-Dist: pyramid-deform
|
|
28
29
|
Requires-Dist: pyramid-mako
|
|
30
|
+
Requires-Dist: pyramid-tm
|
|
29
31
|
Requires-Dist: pyramid>=2
|
|
30
32
|
Requires-Dist: waitress
|
|
31
33
|
Requires-Dist: webhelpers2
|
|
32
|
-
Requires-Dist: wuttjamaican[db]>=0.
|
|
34
|
+
Requires-Dist: wuttjamaican[db]>=0.7.0
|
|
35
|
+
Requires-Dist: zope-sqlalchemy>=1.5
|
|
33
36
|
Provides-Extra: docs
|
|
34
37
|
Requires-Dist: furo; extra == 'docs'
|
|
35
38
|
Requires-Dist: sphinx; extra == 'docs'
|
|
36
39
|
Provides-Extra: tests
|
|
37
40
|
Requires-Dist: pytest-cov; extra == 'tests'
|
|
38
41
|
Requires-Dist: tox; extra == 'tests'
|
|
39
|
-
Description-Content-Type: text/
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
40
43
|
|
|
41
44
|
|
|
42
|
-
|
|
43
|
-
wuttaweb
|
|
44
|
-
==========
|
|
45
|
+
# wuttaweb
|
|
45
46
|
|
|
46
47
|
Web app for Wutta Framework
|
|
47
48
|
|
|
@@ -20,12 +20,15 @@ extensions = [
|
|
|
20
20
|
'sphinx.ext.autodoc',
|
|
21
21
|
'sphinx.ext.intersphinx',
|
|
22
22
|
'sphinx.ext.viewcode',
|
|
23
|
+
'sphinx.ext.todo',
|
|
23
24
|
]
|
|
24
25
|
|
|
25
26
|
templates_path = ['_templates']
|
|
26
27
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|
27
28
|
|
|
28
29
|
intersphinx_mapping = {
|
|
30
|
+
'colander': ('https://docs.pylonsproject.org/projects/colander/en/latest/', None),
|
|
31
|
+
'deform': ('https://docs.pylonsproject.org/projects/deform/en/latest/', None),
|
|
29
32
|
'pyramid': ('https://docs.pylonsproject.org/projects/pyramid/en/latest/', None),
|
|
30
33
|
'python': ('https://docs.python.org/3/', None),
|
|
31
34
|
'webhelpers2': ('https://webhelpers2.readthedocs.io/en/latest/', None),
|
|
@@ -6,6 +6,11 @@ This package provides a "web layer" for custom apps.
|
|
|
6
6
|
|
|
7
7
|
It uses traditional server-side rendering with VueJS on the front-end.
|
|
8
8
|
|
|
9
|
+
Good documentation and 100% `test coverage`_ are priorities for this
|
|
10
|
+
project.
|
|
11
|
+
|
|
12
|
+
.. _test coverage: https://buildbot.rattailproject.org/coverage/wuttaweb/
|
|
13
|
+
|
|
9
14
|
.. toctree::
|
|
10
15
|
:maxdepth: 3
|
|
11
16
|
:caption: Contents:
|
|
@@ -6,9 +6,9 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "WuttaWeb"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.3.0"
|
|
10
10
|
description = "Web App for Wutta Framework"
|
|
11
|
-
readme = "README.
|
|
11
|
+
readme = "README.md"
|
|
12
12
|
authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
|
|
13
13
|
license = {text = "GNU GPL v3+"}
|
|
14
14
|
classifiers = [
|
|
@@ -32,10 +32,13 @@ requires-python = ">= 3.8"
|
|
|
32
32
|
dependencies = [
|
|
33
33
|
"pyramid>=2",
|
|
34
34
|
"pyramid_beaker",
|
|
35
|
+
"pyramid_deform",
|
|
35
36
|
"pyramid_mako",
|
|
37
|
+
"pyramid_tm",
|
|
36
38
|
"waitress",
|
|
37
39
|
"WebHelpers2",
|
|
38
|
-
"WuttJamaican[db]>=0.
|
|
40
|
+
"WuttJamaican[db]>=0.7.0",
|
|
41
|
+
"zope.sqlalchemy>=1.5",
|
|
39
42
|
]
|
|
40
43
|
|
|
41
44
|
|
|
@@ -48,10 +51,14 @@ tests = ["pytest-cov", "tox"]
|
|
|
48
51
|
main = "wuttaweb.app:main"
|
|
49
52
|
|
|
50
53
|
|
|
54
|
+
[project.entry-points."wutta.app.providers"]
|
|
55
|
+
wuttaweb = "wuttaweb.app:WebAppProvider"
|
|
56
|
+
|
|
57
|
+
|
|
51
58
|
[project.urls]
|
|
52
|
-
Homepage = "https://
|
|
53
|
-
Repository = "https://
|
|
54
|
-
Changelog = "https://
|
|
59
|
+
Homepage = "https://wuttaproject.org/"
|
|
60
|
+
Repository = "https://forgejo.wuttaproject.org/wutta/wuttaweb"
|
|
61
|
+
Changelog = "https://forgejo.wuttaproject.org/wutta/wuttaweb/src/branch/master/CHANGELOG.md"
|
|
55
62
|
|
|
56
63
|
|
|
57
64
|
[tool.commitizen]
|
|
@@ -26,10 +26,40 @@ Application
|
|
|
26
26
|
|
|
27
27
|
import os
|
|
28
28
|
|
|
29
|
+
from wuttjamaican.app import AppProvider
|
|
29
30
|
from wuttjamaican.conf import make_config
|
|
30
31
|
|
|
31
32
|
from pyramid.config import Configurator
|
|
32
33
|
|
|
34
|
+
import wuttaweb.db
|
|
35
|
+
from wuttaweb.auth import WuttaSecurityPolicy
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class WebAppProvider(AppProvider):
|
|
39
|
+
"""
|
|
40
|
+
The :term:`app provider` for WuttaWeb. This adds some methods
|
|
41
|
+
specific to web apps.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def get_web_handler(self, **kwargs):
|
|
45
|
+
"""
|
|
46
|
+
Get the configured "web" handler for the app.
|
|
47
|
+
|
|
48
|
+
Specify a custom handler in your config file like this:
|
|
49
|
+
|
|
50
|
+
.. code-block:: ini
|
|
51
|
+
|
|
52
|
+
[wutta]
|
|
53
|
+
web.handler_spec = poser.web.handler:PoserWebHandler
|
|
54
|
+
|
|
55
|
+
:returns: Instance of :class:`~wuttaweb.handler.WebHandler`.
|
|
56
|
+
"""
|
|
57
|
+
if 'web_handler' not in self.__dict__:
|
|
58
|
+
spec = self.config.get(f'{self.appname}.web.handler_spec',
|
|
59
|
+
default='wuttaweb.handler:WebHandler')
|
|
60
|
+
self.web_handler = self.app.load_object(spec)(self.config)
|
|
61
|
+
return self.web_handler
|
|
62
|
+
|
|
33
63
|
|
|
34
64
|
def make_wutta_config(settings):
|
|
35
65
|
"""
|
|
@@ -56,17 +86,21 @@ def make_wutta_config(settings):
|
|
|
56
86
|
|
|
57
87
|
If this config file path cannot be discovered, an error is raised.
|
|
58
88
|
"""
|
|
59
|
-
#
|
|
60
|
-
# available for web requests later
|
|
89
|
+
# validate config file path
|
|
61
90
|
path = settings.get('wutta.config')
|
|
62
91
|
if not path or not os.path.exists(path):
|
|
63
92
|
raise ValueError("Please set 'wutta.config' in [app:main] "
|
|
64
93
|
"section of config to the path of your "
|
|
65
94
|
"config file. Lame, but necessary.")
|
|
66
95
|
|
|
96
|
+
# make config per usual, add to settings
|
|
67
97
|
wutta_config = make_config(path)
|
|
68
|
-
|
|
69
98
|
settings['wutta_config'] = wutta_config
|
|
99
|
+
|
|
100
|
+
# configure database sessions
|
|
101
|
+
if hasattr(wutta_config, 'appdb_engine'):
|
|
102
|
+
wuttaweb.db.Session.configure(bind=wutta_config.appdb_engine)
|
|
103
|
+
|
|
70
104
|
return wutta_config
|
|
71
105
|
|
|
72
106
|
|
|
@@ -77,10 +111,18 @@ def make_pyramid_config(settings):
|
|
|
77
111
|
The config is initialized with certain features deemed useful for
|
|
78
112
|
all apps.
|
|
79
113
|
"""
|
|
114
|
+
settings.setdefault('pyramid_deform.template_search_path',
|
|
115
|
+
'wuttaweb:templates/deform')
|
|
116
|
+
|
|
80
117
|
pyramid_config = Configurator(settings=settings)
|
|
81
118
|
|
|
119
|
+
# configure user authorization / authentication
|
|
120
|
+
pyramid_config.set_security_policy(WuttaSecurityPolicy())
|
|
121
|
+
|
|
82
122
|
pyramid_config.include('pyramid_beaker')
|
|
123
|
+
pyramid_config.include('pyramid_deform')
|
|
83
124
|
pyramid_config.include('pyramid_mako')
|
|
125
|
+
pyramid_config.include('pyramid_tm')
|
|
84
126
|
|
|
85
127
|
return pyramid_config
|
|
86
128
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# -*- coding: utf-8; -*-
|
|
2
|
+
################################################################################
|
|
3
|
+
#
|
|
4
|
+
# wuttaweb -- Web App for Wutta Framework
|
|
5
|
+
# Copyright © 2024 Lance Edgar
|
|
6
|
+
#
|
|
7
|
+
# This file is part of Wutta Framework.
|
|
8
|
+
#
|
|
9
|
+
# Wutta Framework is free software: you can redistribute it and/or modify it
|
|
10
|
+
# under the terms of the GNU General Public License as published by the Free
|
|
11
|
+
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
12
|
+
# later version.
|
|
13
|
+
#
|
|
14
|
+
# Wutta Framework is distributed in the hope that it will be useful, but
|
|
15
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
17
|
+
# more details.
|
|
18
|
+
#
|
|
19
|
+
# You should have received a copy of the GNU General Public License along with
|
|
20
|
+
# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
#
|
|
22
|
+
################################################################################
|
|
23
|
+
"""
|
|
24
|
+
Auth Utility Logic
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
import re
|
|
28
|
+
|
|
29
|
+
from pyramid.authentication import SessionAuthenticationHelper
|
|
30
|
+
from pyramid.request import RequestLocalCache
|
|
31
|
+
from pyramid.security import remember, forget
|
|
32
|
+
|
|
33
|
+
from wuttaweb.db import Session
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def login_user(request, user):
|
|
37
|
+
"""
|
|
38
|
+
Perform the steps necessary to "login" the given user. This
|
|
39
|
+
returns a ``headers`` dict which you should pass to the final
|
|
40
|
+
redirect, like so::
|
|
41
|
+
|
|
42
|
+
from pyramid.httpexceptions import HTTPFound
|
|
43
|
+
|
|
44
|
+
headers = login_user(request, user)
|
|
45
|
+
return HTTPFound(location='/', headers=headers)
|
|
46
|
+
|
|
47
|
+
.. warning::
|
|
48
|
+
|
|
49
|
+
This logic does not "authenticate" the user! It assumes caller
|
|
50
|
+
has already authenticated the user and they are safe to login.
|
|
51
|
+
|
|
52
|
+
See also :func:`logout_user()`.
|
|
53
|
+
"""
|
|
54
|
+
headers = remember(request, user.uuid)
|
|
55
|
+
return headers
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def logout_user(request):
|
|
59
|
+
"""
|
|
60
|
+
Perform the logout action for the given request. This returns a
|
|
61
|
+
``headers`` dict which you should pass to the final redirect, like
|
|
62
|
+
so::
|
|
63
|
+
|
|
64
|
+
from pyramid.httpexceptions import HTTPFound
|
|
65
|
+
|
|
66
|
+
headers = logout_user(request)
|
|
67
|
+
return HTTPFound(location='/', headers=headers)
|
|
68
|
+
|
|
69
|
+
See also :func:`login_user()`.
|
|
70
|
+
"""
|
|
71
|
+
request.session.delete()
|
|
72
|
+
request.session.invalidate()
|
|
73
|
+
headers = forget(request)
|
|
74
|
+
return headers
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class WuttaSecurityPolicy:
|
|
78
|
+
"""
|
|
79
|
+
Pyramid :term:`security policy` for WuttaWeb.
|
|
80
|
+
|
|
81
|
+
For more on the Pyramid details, see :doc:`pyramid:narr/security`.
|
|
82
|
+
|
|
83
|
+
But the idea here is that you should be able to just use this,
|
|
84
|
+
without thinking too hard::
|
|
85
|
+
|
|
86
|
+
from pyramid.config import Configurator
|
|
87
|
+
from wuttaweb.auth import WuttaSecurityPolicy
|
|
88
|
+
|
|
89
|
+
pyramid_config = Configurator()
|
|
90
|
+
pyramid_config.set_security_policy(WuttaSecurityPolicy())
|
|
91
|
+
|
|
92
|
+
This security policy will then do the following:
|
|
93
|
+
|
|
94
|
+
* use the request "web session" for auth storage (e.g. current
|
|
95
|
+
``user.uuid``)
|
|
96
|
+
* check permissions as needed, by calling
|
|
97
|
+
:meth:`~wuttjamaican:wuttjamaican.auth.AuthHandler.has_permission()`
|
|
98
|
+
for current user
|
|
99
|
+
|
|
100
|
+
:param db_session: Optional :term:`db session` to use, instead of
|
|
101
|
+
:class:`wuttaweb.db.Session`. Probably only useful for tests.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def __init__(self, db_session=None):
|
|
105
|
+
self.session_helper = SessionAuthenticationHelper()
|
|
106
|
+
self.identity_cache = RequestLocalCache(self.load_identity)
|
|
107
|
+
self.db_session = db_session or Session()
|
|
108
|
+
|
|
109
|
+
def load_identity(self, request):
|
|
110
|
+
config = request.registry.settings['wutta_config']
|
|
111
|
+
app = config.get_app()
|
|
112
|
+
model = app.model
|
|
113
|
+
|
|
114
|
+
# fetch user uuid from current session
|
|
115
|
+
uuid = self.session_helper.authenticated_userid(request)
|
|
116
|
+
if not uuid:
|
|
117
|
+
return
|
|
118
|
+
|
|
119
|
+
# fetch user object from db
|
|
120
|
+
user = self.db_session.get(model.User, uuid)
|
|
121
|
+
if not user:
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
return user
|
|
125
|
+
|
|
126
|
+
def identity(self, request):
|
|
127
|
+
return self.identity_cache.get_or_create(request)
|
|
128
|
+
|
|
129
|
+
def authenticated_userid(self, request):
|
|
130
|
+
user = self.identity(request)
|
|
131
|
+
if user is not None:
|
|
132
|
+
return user.uuid
|
|
133
|
+
|
|
134
|
+
def remember(self, request, userid, **kw):
|
|
135
|
+
return self.session_helper.remember(request, userid, **kw)
|
|
136
|
+
|
|
137
|
+
def forget(self, request, **kw):
|
|
138
|
+
return self.session_helper.forget(request, **kw)
|
|
139
|
+
|
|
140
|
+
def permits(self, request, context, permission):
|
|
141
|
+
|
|
142
|
+
# nb. root user can do anything
|
|
143
|
+
if getattr(request, 'is_root', False):
|
|
144
|
+
return True
|
|
145
|
+
|
|
146
|
+
config = request.registry.settings['wutta_config']
|
|
147
|
+
app = config.get_app()
|
|
148
|
+
auth = app.get_auth_handler()
|
|
149
|
+
user = self.identity(request)
|
|
150
|
+
return auth.has_permission(self.db_session, user, permission)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# -*- coding: utf-8; -*-
|
|
2
|
+
################################################################################
|
|
3
|
+
#
|
|
4
|
+
# wuttaweb -- Web App for Wutta Framework
|
|
5
|
+
# Copyright © 2024 Lance Edgar
|
|
6
|
+
#
|
|
7
|
+
# This file is part of Wutta Framework.
|
|
8
|
+
#
|
|
9
|
+
# Wutta Framework is free software: you can redistribute it and/or modify it
|
|
10
|
+
# under the terms of the GNU General Public License as published by the Free
|
|
11
|
+
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
12
|
+
# later version.
|
|
13
|
+
#
|
|
14
|
+
# Wutta Framework is distributed in the hope that it will be useful, but
|
|
15
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
17
|
+
# more details.
|
|
18
|
+
#
|
|
19
|
+
# You should have received a copy of the GNU General Public License along with
|
|
20
|
+
# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
#
|
|
22
|
+
################################################################################
|
|
23
|
+
"""
|
|
24
|
+
Database sessions for web app
|
|
25
|
+
|
|
26
|
+
The web app uses a different database session than other
|
|
27
|
+
(e.g. console) apps. The web session is "registered" to the HTTP
|
|
28
|
+
request/response life cycle (aka. transaction) such that the session
|
|
29
|
+
is automatically rolled back on error, and automatically committed if
|
|
30
|
+
the response is finalized without error.
|
|
31
|
+
|
|
32
|
+
.. class:: Session
|
|
33
|
+
|
|
34
|
+
Primary database session class for the web app.
|
|
35
|
+
|
|
36
|
+
Note that you often do not need to "instantiate" this session, and
|
|
37
|
+
can instead call methods directly on the class::
|
|
38
|
+
|
|
39
|
+
from wuttaweb.db import Session
|
|
40
|
+
|
|
41
|
+
users = Session.query(model.User).all()
|
|
42
|
+
|
|
43
|
+
However in certain cases you may still want/need to instantiate it,
|
|
44
|
+
e.g. when passing a "true/normal" session to other logic. But you
|
|
45
|
+
can always call instance methods as well::
|
|
46
|
+
|
|
47
|
+
from wuttaweb.db import Session
|
|
48
|
+
from some_place import some_func
|
|
49
|
+
|
|
50
|
+
session = Session()
|
|
51
|
+
|
|
52
|
+
# nb. assuming func does not expect a "web" session per se, pass instance
|
|
53
|
+
some_func(session)
|
|
54
|
+
|
|
55
|
+
# nb. these behave the same (instance vs. class method)
|
|
56
|
+
users = session.query(model.User).all()
|
|
57
|
+
users = Session.query(model.User).all()
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
from sqlalchemy import orm
|
|
61
|
+
from zope.sqlalchemy.datamanager import register
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Session = orm.scoped_session(orm.sessionmaker())
|
|
65
|
+
|
|
66
|
+
register(Session)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# -*- coding: utf-8; -*-
|
|
2
|
+
################################################################################
|
|
3
|
+
#
|
|
4
|
+
# wuttaweb -- Web App for Wutta Framework
|
|
5
|
+
# Copyright © 2024 Lance Edgar
|
|
6
|
+
#
|
|
7
|
+
# This file is part of Wutta Framework.
|
|
8
|
+
#
|
|
9
|
+
# Wutta Framework is free software: you can redistribute it and/or modify it
|
|
10
|
+
# under the terms of the GNU General Public License as published by the Free
|
|
11
|
+
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
12
|
+
# later version.
|
|
13
|
+
#
|
|
14
|
+
# Wutta Framework is distributed in the hope that it will be useful, but
|
|
15
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
17
|
+
# more details.
|
|
18
|
+
#
|
|
19
|
+
# You should have received a copy of the GNU General Public License along with
|
|
20
|
+
# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
#
|
|
22
|
+
################################################################################
|
|
23
|
+
"""
|
|
24
|
+
Forms Library
|
|
25
|
+
|
|
26
|
+
The ``wuttaweb.forms`` namespace contains the following:
|
|
27
|
+
|
|
28
|
+
* :class:`~wuttaweb.forms.base.Form`
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
from .base import Form
|