瀏覽代碼

Merge branch 'feature/51_restore_mail_notifier' of github.com:tracim/tracim_backend into feature/51_restore_mail_notifier

Guénaël Muller 6 年之前
父節點
當前提交
aaba36a9b8
共有 7 個文件被更改,包括 145 次插入12 次删除
  1. 28 8
      README.md
  2. 4 0
      tracim/__init__.py
  3. 77 0
      tracim/lib/utils/cors.py
  4. 11 2
      tracim/tests/functional/test_session.py
  5. 4 2
      tracim/views/core_api/session_controller.py
  6. 9 0
      wsgi/web.py
  7. 12 0
      wsgi/webdav.py

+ 28 - 8
README.md 查看文件

74
 
74
 
75
     tracimcli db init
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
 run wsgidav server:
110
 run wsgidav server:
90
 
111
 
91
     tracimcli webdav start
112
     tracimcli webdav start
92
 
113
 
93
-### Run Tests ###
114
+## Run Tests and others checks ##
94
 
115
 
95
 Before running some functional test related to email, you need a local working *MailHog*
116
 Before running some functional test related to email, you need a local working *MailHog*
96
 see here : https://github.com/mailhog/MailHog
117
 see here : https://github.com/mailhog/MailHog
100
     docker pull mailhog/mailhog
121
     docker pull mailhog/mailhog
101
     docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
122
     docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog
102
 
123
 
103
-
104
 Run your project's tests:
124
 Run your project's tests:
105
 
125
 
106
     pytest
126
     pytest

+ 4 - 0
tracim/__init__.py 查看文件

16
 from tracim.views import BASE_API_V2
16
 from tracim.views import BASE_API_V2
17
 from tracim.views.core_api.session_controller import SessionController
17
 from tracim.views.core_api.session_controller import SessionController
18
 from tracim.views.errors import ErrorSchema
18
 from tracim.views.errors import ErrorSchema
19
+from tracim.lib.utils.cors import add_cors_support
19
 
20
 
20
 
21
 
21
 def main(global_config, **settings):
22
 def main(global_config, **settings):
31
         basic_auth_check_credentials,
32
         basic_auth_check_credentials,
32
         realm=BASIC_AUTH_WEBUI_REALM,
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
     # Default authorization : Accept anything.
38
     # Default authorization : Accept anything.
35
     configurator.set_authorization_policy(AcceptAllAuthorizationPolicy())
39
     configurator.set_authorization_policy(AcceptAllAuthorizationPolicy())
36
     configurator.set_authentication_policy(authn_policy)
40
     configurator.set_authentication_policy(authn_policy)

+ 77 - 0
tracim/lib/utils/cors.py 查看文件

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 查看文件

37
 
37
 
38
 class TestLoginEndpoint(FunctionalTest):
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
         params = {
41
         params = {
42
             'email': 'admin@admin.admin',
42
             'email': 'admin@admin.admin',
43
             'password': 'admin@admin.admin',
43
             'password': 'admin@admin.admin',
45
         res = self.testapp.post_json(
45
         res = self.testapp.post_json(
46
             '/api/v2/sessions/login',
46
             '/api/v2/sessions/login',
47
             params=params,
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
     def test_api__try_login_enpoint__err_400__bad_password(self):
60
     def test_api__try_login_enpoint__err_400__bad_password(self):
52
         params = {
61
         params = {

+ 4 - 2
tracim/views/core_api/session_controller.py 查看文件

25
     @hapic.handle_exception(AuthenticationFailed, HTTPStatus.BAD_REQUEST)
25
     @hapic.handle_exception(AuthenticationFailed, HTTPStatus.BAD_REQUEST)
26
     # TODO - G.M - 17-04-2018 - fix output header ?
26
     # TODO - G.M - 17-04-2018 - fix output header ?
27
     # @hapic.output_headers()
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
     def login(self, context, request: TracimRequest, hapic_data=None):
30
     def login(self, context, request: TracimRequest, hapic_data=None):
30
         """
31
         """
31
         Logs user into the system
32
         Logs user into the system
38
             session=request.dbsession,
39
             session=request.dbsession,
39
             config=app_config,
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
     @hapic.with_api_doc()
45
     @hapic.with_api_doc()
44
     @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8
46
     @hapic.output_body(NoContentSchema(), default_http_code=HTTPStatus.NO_CONTENT)  # nopep8

+ 9 - 0
wsgi/web.py 查看文件

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 查看文件

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()