Browse Source

add basic_auth + simple pyramid auth acl example

Guénaël Muller 7 years ago
parent
commit
1965b24977
3 changed files with 81 additions and 0 deletions
  1. 9 0
      tracim/__init__.py
  2. 22 0
      tracim/lib/utils/auth.py
  3. 50 0
      tracim/views/default/default_controller.py

+ 9 - 0
tracim/__init__.py View File

@@ -3,10 +3,14 @@ import json
3 3
 import time
4 4
 
5 5
 from pyramid.config import Configurator
6
+from pyramid.authentication import BasicAuthAuthenticationPolicy
7
+from pyramid.authorization import ACLAuthorizationPolicy
6 8
 from hapic.ext.pyramid import PyramidContext
7 9
 
8 10
 from tracim.extensions import hapic
9 11
 from tracim.config import CFG
12
+from tracim.lib.utils.auth import check_credentials
13
+from tracim.lib.utils.auth import Root
10 14
 from tracim.views.example_api.example_api_controller import ExampleApiController
11 15
 from tracim.views.default.default_controller import DefaultController
12 16
 
@@ -19,6 +23,11 @@ def main(global_config, **settings):
19 23
     app_config.configure_filedepot()
20 24
     settings['CFG'] = app_config
21 25
     configurator = Configurator(settings=settings, autocommit=True)
26
+    # Add BasicAuthPolicy + ACL AuthorizationPolicy
27
+    authn_policy = BasicAuthAuthenticationPolicy(check_credentials)
28
+    configurator.set_authorization_policy(ACLAuthorizationPolicy())
29
+    configurator.set_authentication_policy(authn_policy)
30
+    configurator.set_root_factory(lambda request: Root())
22 31
     # Pyramids "plugin" include.
23 32
     configurator.include('pyramid_jinja2')
24 33
     # Add SqlAlchemy DB

+ 22 - 0
tracim/lib/utils/auth.py View File

@@ -0,0 +1,22 @@
1
+from pyramid.security import ALL_PERMISSIONS
2
+from pyramid.security import Allow
3
+from pyramid.security import Authenticated
4
+
5
+
6
+def check_credentials(username, password, request):
7
+    if username == 'admin' and password == 'admin':
8
+        # an empty list is enough to indicate logged-in... watch how this
9
+        # affects the principals returned in the home view if you want to
10
+        # expand ACLs later
11
+        return ['g:admin']
12
+    if username == 'user' and password == 'user':
13
+        return []
14
+
15
+
16
+class Root:
17
+    # dead simple, give everyone who is logged in any permission
18
+    # (see the home_view for an example permission)
19
+    __acl__ = (
20
+        (Allow, 'g:admin', ALL_PERMISSIONS),
21
+        (Allow, Authenticated, 'user'),
22
+    )

+ 50 - 0
tracim/views/default/default_controller.py View File

@@ -3,6 +3,9 @@ from tracim.views.controllers import Controller
3 3
 from pyramid.config import Configurator
4 4
 from pyramid.response import Response
5 5
 from pyramid.exceptions import NotFound
6
+from pyramid.httpexceptions import HTTPUnauthorized
7
+from pyramid.httpexceptions import HTTPForbidden
8
+from pyramid.security import forget
6 9
 
7 10
 
8 11
 class DefaultController(Controller):
@@ -13,6 +16,17 @@ class DefaultController(Controller):
13 16
         return {}
14 17
 
15 18
     @classmethod
19
+    def forbidden_view(cls, request):
20
+        if request.authenticated_userid is None:
21
+            response = HTTPUnauthorized()
22
+            response.headers.update(forget(request))
23
+
24
+        # user is logged in but doesn't have permissions, reject wholesale
25
+        else:
26
+            response = HTTPForbidden()
27
+        return response
28
+
29
+    @classmethod
16 30
     def test_config(cls, request):
17 31
         try:
18 32
             app_config = request.registry.settings['CFG']
@@ -21,6 +35,25 @@ class DefaultController(Controller):
21 35
             return Response(e, content_type='text/plain', status=500)
22 36
         return {'project': project}
23 37
 
38
+    @classmethod
39
+    def test_admin_page(cls, request):
40
+        try:
41
+            app_config = request.registry.settings['CFG']
42
+            project = 'admin'
43
+        except Exception as e:
44
+            return Response(e, content_type='text/plain', status=500)
45
+        return {'project': project}
46
+
47
+    @classmethod
48
+    def test_user_page(cls, request):
49
+        try:
50
+            app_config = request.registry.settings['CFG']
51
+            project = 'user'
52
+        except Exception as e:
53
+            return Response(e, content_type='text/plain', status=500)
54
+        return {'project': project}
55
+
56
+
24 57
     def bind(self, configurator: Configurator):
25 58
         configurator.add_static_view('static', 'static', cache_max_age=3600)
26 59
         configurator.add_view(
@@ -35,3 +68,20 @@ class DefaultController(Controller):
35 68
             route_name='test_config',
36 69
             renderer='tracim:templates/mytemplate.jinja2',
37 70
         )
71
+
72
+        configurator.add_route('test_admin', '/test_admin')
73
+        configurator.add_view(
74
+            self.test_admin_page,
75
+            route_name='test_admin',
76
+            renderer='tracim:templates/mytemplate.jinja2',
77
+            permission='admin',
78
+        )
79
+
80
+        configurator.add_route('test_user', '/test_user')
81
+        configurator.add_view(
82
+            self.test_user_page,
83
+            route_name='test_user',
84
+            renderer='tracim:templates/mytemplate.jinja2',
85
+            permission='user',
86
+        )
87
+        configurator.add_forbidden_view(self.forbidden_view)