Browse Source

Merge branch 'develop' into feature/51_restore_mail_notifier

inkhey 6 years ago
parent
commit
c6723433e5
No account linked to committer's email

+ 28 - 8
README.md View File

@@ -74,23 +74,44 @@ Initialize the database using [tracimcli](doc/cli.md) tool
74 74
 
75 75
     tracimcli db init
76 76
 
77
-### Run Tracim_backend ###
77
+create wsgidav configuration file for webdav:
78 78
 
79
-Run your project:
79
+    cp wsgidav.conf.sample wsgidav.conf
80 80
 
81
-    pserve development.ini
81
+## Run Tracim_backend ##
82 82
 
83
-### Configure and Run Webdav Server (Unstable) ###
83
+### With Uwsgi ###
84 84
 
85
-create wsgidav configuration file :
85
+Run all services with uwsgi
86 86
 
87
-    cp wsgidav.conf.sample wsgidav.conf
87
+    # install uwsgi with pip ( unneeded if you already have uwsgi with python3 plugin enabled)
88
+    sudo pip3 install uwsgi
89
+    # set tracim_conf_file path
90
+    export TRACIM_CONF_PATH="$(pwd)/development.ini"
91
+    export TRACIM_WEBDAV_CONF_PATH="$(pwd)/wsgidav.conf"
92
+    # pyramid webserver
93
+    uwsgi -d /tmp/tracim_web.log --http-socket :6543 --wsgi-file wsgi/web.py -H env --pidfile /tmp/tracim_web.pid
94
+    # webdav wsgidav server
95
+    uwsgi -d /tmp/tracim_webdav.log --http-socket :3030 --wsgi-file wsgi/webdav.py -H env --pidfile /tmp/tracim_webdav.pid
96
+
97
+to stop them:
98
+
99
+    # pyramid webserver
100
+    uwsgi --stop /tmp/tracim_web.pid
101
+    # webdav wsgidav server
102
+    uwsgi --stop /tmp/tracim_webdav.pid
103
+
104
+### With Waitress (legacy way, usefull for debug) ###
105
+
106
+run tracim_backend web api:
107
+
108
+    pserve developement.ini
88 109
 
89 110
 run wsgidav server:
90 111
 
91 112
     tracimcli webdav start
92 113
 
93
-### Run Tests ###
114
+## Run Tests and others checks ##
94 115
 
95 116
 Before running some functional test related to email, you need a local working *MailHog*
96 117
 see here : https://github.com/mailhog/MailHog
@@ -100,7 +121,6 @@ You can run it this way with docker :
100 121
     docker pull mailhog/mailhog
101 122
     docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
102 123
 
103
-
104 124
 Run your project's tests:
105 125
 
106 126
     pytest

+ 4 - 0
tracim/__init__.py View File

@@ -16,6 +16,7 @@ from tracim.lib.utils.authorization import TRACIM_DEFAULT_PERM
16 16
 from tracim.views import BASE_API_V2
17 17
 from tracim.views.core_api.session_controller import SessionController
18 18
 from tracim.views.errors import ErrorSchema
19
+from tracim.lib.utils.cors import add_cors_support
19 20
 
20 21
 
21 22
 def main(global_config, **settings):
@@ -31,6 +32,9 @@ def main(global_config, **settings):
31 32
         basic_auth_check_credentials,
32 33
         realm=BASIC_AUTH_WEBUI_REALM,
33 34
     )
35
+    configurator.include(add_cors_support)
36
+    # make sure to add this before other routes to intercept OPTIONS
37
+    configurator.add_cors_preflight_handler()
34 38
     # Default authorization : Accept anything.
35 39
     configurator.set_authorization_policy(AcceptAllAuthorizationPolicy())
36 40
     configurator.set_authentication_policy(authn_policy)

+ 77 - 0
tracim/lib/utils/cors.py View File

@@ -0,0 +1,77 @@
1
+# -*- coding: utf-8 -*-
2
+# INFO - G.M -17-05-2018 - CORS support
3
+# original code from https://gist.github.com/mmerickel/1afaf64154b335b596e4
4
+# see also
5
+# here : https://groups.google.com/forum/#!topic/pylons-discuss/2Sw4OkOnZcE
6
+from pyramid.events import NewResponse
7
+
8
+
9
+def add_cors_support(config):
10
+    # INFO - G.M - 17-05-2018 - CORS Preflight stuff (special requests)
11
+    config.add_directive(
12
+        'add_cors_preflight_handler',
13
+        add_cors_preflight_handler
14
+    )
15
+    config.add_route_predicate('cors_preflight', CorsPreflightPredicate)
16
+
17
+    # INFO - G.M - 17-05-2018 CORS Headers for all responses
18
+    config.add_subscriber(add_cors_to_response, NewResponse)
19
+
20
+
21
+class CorsPreflightPredicate(object):
22
+    def __init__(self, val, config):
23
+        self.val = val
24
+
25
+    def text(self):
26
+        return 'cors_preflight = %s' % bool(self.val)
27
+
28
+    phash = text
29
+
30
+    def __call__(self, context, request):
31
+        if not self.val:
32
+            return False
33
+        return (
34
+            request.method == 'OPTIONS' and
35
+            'Origin' in request.headers and
36
+            'Access-Control-Request-Method' in request.headers
37
+        )
38
+
39
+
40
+def add_cors_preflight_handler(config):
41
+    # INFO - G.M - 17-05-2018 - Add route for CORS preflight
42
+    # see https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
43
+    # for more info about preflight
44
+
45
+    config.add_route(
46
+        'cors-options-preflight', '/{catch_all:.*}',
47
+        cors_preflight=True,
48
+    )
49
+    config.add_view(
50
+        cors_options_view,
51
+        route_name='cors-options-preflight',
52
+    )
53
+
54
+
55
+def cors_options_view(context, request):
56
+    response = request.response
57
+    if 'Access-Control-Request-Headers' in request.headers:
58
+        response.headers['Access-Control-Allow-Methods'] = (
59
+            'OPTIONS,HEAD,GET,POST,PUT,DELETE'
60
+        )
61
+    response.headers['Access-Control-Allow-Headers'] = (
62
+        'Content-Type,Accept,Accept-Language,Authorization,X-Request-ID'
63
+    )
64
+    return response
65
+
66
+
67
+def add_cors_to_response(event):
68
+    # INFO - G.M - 17-05-2018 - Add some CORS headers to all requests
69
+    request = event.request
70
+    response = event.response
71
+    if 'Origin' in request.headers:
72
+        response.headers['Access-Control-Expose-Headers'] = (
73
+            'Content-Type,Date,Content-Length,Authorization,X-Request-ID'
74
+        )
75
+        # TODO - G.M - 17-05-2018 - Allow to configure this header in config
76
+        response.headers['Access-Control-Allow-Origin'] = '*'
77
+        response.headers['Access-Control-Allow-Credentials'] = 'true'

+ 11 - 2
tracim/tests/functional/test_session.py View File

@@ -37,7 +37,7 @@ class TestLoginEndpointUnititedDB(FunctionalTestNoDB):
37 37
 
38 38
 class TestLoginEndpoint(FunctionalTest):
39 39
 
40
-    def test_api__try_login_enpoint__ok_204__nominal_case(self):
40
+    def test_api__try_login_enpoint__ok_200__nominal_case(self):
41 41
         params = {
42 42
             'email': 'admin@admin.admin',
43 43
             'password': 'admin@admin.admin',
@@ -45,8 +45,17 @@ class TestLoginEndpoint(FunctionalTest):
45 45
         res = self.testapp.post_json(
46 46
             '/api/v2/sessions/login',
47 47
             params=params,
48
-            status=204,
48
+            status=200,
49 49
         )
50
+        assert res.json_body['display_name'] == 'Global manager'
51
+        assert res.json_body['email'] == 'admin@admin.admin'
52
+        assert res.json_body['created']
53
+        assert res.json_body['is_active']
54
+        assert res.json_body['profile']
55
+        assert isinstance(res.json_body['profile']['id'], int)
56
+        assert res.json_body['profile']['slug'] == 'administrators'
57
+        assert res.json_body['caldav_url'] is None
58
+        assert res.json_body['avatar_url'] is None
50 59
 
51 60
     def test_api__try_login_enpoint__err_400__bad_password(self):
52 61
         params = {

+ 4 - 2
tracim/views/core_api/session_controller.py View File

@@ -25,7 +25,8 @@ class SessionController(Controller):
25 25
     @hapic.handle_exception(AuthenticationFailed, HTTPStatus.BAD_REQUEST)
26 26
     # TODO - G.M - 17-04-2018 - fix output header ?
27 27
     # @hapic.output_headers()
28
-    @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
28
+    @hapic.output_body(UserSchema(),)
29
+    #@hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
29 30
     def login(self, context, request: TracimRequest, hapic_data=None):
30 31
         """
31 32
         Logs user into the system
@@ -38,7 +39,8 @@ class SessionController(Controller):
38 39
             session=request.dbsession,
39 40
             config=app_config,
40 41
         )
41
-        return uapi.authenticate_user(login.email, login.password)
42
+        user = uapi.authenticate_user(login.email, login.password)
43
+        return uapi.get_user_with_context(user)
42 44
 
43 45
     @hapic.with_api_doc()
44 46
     @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8

+ 9 - 0
wsgi/web.py View File

@@ -0,0 +1,9 @@
1
+# coding=utf-8
2
+# Runner for uwsgi
3
+import os
4
+import pyramid.paster
5
+
6
+config_uri = os.environ['TRACIM_CONF_PATH']
7
+
8
+pyramid.paster.setup_logging(config_uri)
9
+application = pyramid.paster.get_app(config_uri)

+ 12 - 0
wsgi/webdav.py View File

@@ -0,0 +1,12 @@
1
+# coding=utf-8
2
+# Runner for uwsgi
3
+from tracim.lib.webdav import WebdavAppFactory
4
+import os
5
+
6
+config_uri = os.environ['TRACIM_CONF_PATH']
7
+webdav_config_uri = os.environ['TRACIM_WEBDAV_CONF_PATH']
8
+app_factory = WebdavAppFactory(
9
+    tracim_config_file_path=config_uri,
10
+    webdav_config_file_path=webdav_config_uri,
11
+)
12
+application = app_factory.get_wsgi_app()