Преглед изворни кода

Merge pull request #20 from tracim/feature/613_user_invitation_admin

Bastien Sevajol пре 6 година
родитељ
комит
b7a216eb88
No account linked to committer's email

+ 5 - 4
backend/tracim_backend/command/user.py Прегледај датотеку

@@ -127,7 +127,8 @@ class UserCommand(AppContextCommand):
127 127
                     "You must provide -p/--password parameter"
128 128
                 )
129 129
             password = ''
130
-
130
+        if self._user_api.check_email_already_in_db(login):
131
+            raise UserAlreadyExistError()
131 132
         try:
132 133
             user = self._user_api.create_user(
133 134
                 email=login,
@@ -140,12 +141,12 @@ class UserCommand(AppContextCommand):
140 141
             # daemons = DaemonsManager()
141 142
             # daemons.run('radicale', RadicaleDaemon)
142 143
             self._user_api.execute_created_user_actions(user)
143
-        except IntegrityError:
144
+        except IntegrityError as exception:
144 145
             self._session.rollback()
145
-            raise UserAlreadyExistError()
146
+            raise UserAlreadyExistError() from exception
146 147
         except NotificationNotSend as exception:
147 148
             self._session.rollback()
148
-            raise exception
149
+            raise exception from exception
149 150
 
150 151
         return user
151 152
 

+ 4 - 0
backend/tracim_backend/exceptions.py Прегледај датотеку

@@ -213,3 +213,7 @@ class TooShortAutocompleteString(TracimException):
213 213
 
214 214
 class PageNotFound(TracimException):
215 215
     pass
216
+
217
+
218
+class EmailAlreadyExistInDb(TracimException):
219
+    pass

+ 30 - 8
backend/tracim_backend/lib/core/user.py Прегледај датотеку

@@ -13,6 +13,7 @@ from tracim_backend.config import CFG
13 13
 from tracim_backend.models.auth import User
14 14
 from tracim_backend.models.auth import Group
15 15
 from tracim_backend.exceptions import NoUserSetted
16
+from tracim_backend.exceptions import EmailAlreadyExistInDb
16 17
 from tracim_backend.exceptions import TooShortAutocompleteString
17 18
 from tracim_backend.exceptions import PasswordDoNotMatch
18 19
 from tracim_backend.exceptions import EmailValidationFailed
@@ -272,6 +273,32 @@ class UserApi(object):
272 273
         return user
273 274
 
274 275
     def _check_email(self, email: str) -> bool:
276
+        """
277
+        Check if email is completely ok to be used in user db table
278
+        """
279
+        is_email_correct = self._check_email_correctness(email)
280
+        if not is_email_correct:
281
+            raise EmailValidationFailed(
282
+                'Email given form {} is uncorrect'.format(email))  # nopep8
283
+        email_already_exist_in_db = self.check_email_already_in_db(email)
284
+        if email_already_exist_in_db:
285
+            raise EmailAlreadyExistInDb(
286
+                'Email given {} already exist, please choose something else'.format(email)  # nopep8
287
+            )
288
+        return True
289
+
290
+    def check_email_already_in_db(self, email: str) -> bool:
291
+        """
292
+        Verify if given email does not already exist in db
293
+        """
294
+        return self._session.query(User.email).filter(User.email==email).count() != 0  # nopep8
295
+
296
+    def _check_email_correctness(self, email: str) -> bool:
297
+        """
298
+           Verify if given email is correct:
299
+           - check format
300
+           - futur active check for email ? (dns based ?)
301
+           """
275 302
         # TODO - G.M - 2018-07-05 - find a better way to check email
276 303
         if not email:
277 304
             return False
@@ -293,10 +320,8 @@ class UserApi(object):
293 320
         if name is not None:
294 321
             user.display_name = name
295 322
 
296
-        if email is not None:
297
-            email_exist = self._check_email(email)
298
-            if not email_exist:
299
-                raise EmailValidationFailed('Email given form {} is uncorrect'.format(email))  # nopep8
323
+        if email is not None and email != user.email:
324
+            self._check_email(email)
300 325
             user.email = email
301 326
 
302 327
         if password is not None:
@@ -359,11 +384,8 @@ class UserApi(object):
359 384
             save_now=False
360 385
     ) -> User:
361 386
         """Previous create_user method"""
387
+        self._check_email(email)
362 388
         user = User()
363
-
364
-        email_exist = self._check_email(email)
365
-        if not email_exist:
366
-            raise EmailValidationFailed('Email given form {} is uncorrect'.format(email))  # nopep8
367 389
         user.email = email
368 390
         user.display_name = email.split('@')[0]
369 391
 

+ 13 - 9
backend/tracim_backend/models/context_models.py Прегледај датотеку

@@ -8,10 +8,12 @@ from sqlalchemy.orm import Session
8 8
 from tracim_backend.config import CFG
9 9
 from tracim_backend.config import PreviewDim
10 10
 from tracim_backend.lib.utils.utils import get_root_frontend_url
11
+from tracim_backend.lib.utils.utils import password_generator
11 12
 from tracim_backend.lib.utils.utils import CONTENT_FRONTEND_URL_SCHEMA
12 13
 from tracim_backend.lib.utils.utils import WORKSPACE_FRONTEND_URL_SCHEMA
13 14
 from tracim_backend.models import User
14 15
 from tracim_backend.models.auth import Profile
16
+from tracim_backend.models.auth import Group
15 17
 from tracim_backend.models.data import Content
16 18
 from tracim_backend.models.data import ContentRevisionRO
17 19
 from tracim_backend.models.data import Workspace
@@ -99,17 +101,19 @@ class UserCreation(object):
99 101
     def __init__(
100 102
             self,
101 103
             email: str,
102
-            password: str,
103
-            public_name: str,
104
-            timezone: str,
105
-            profile: str,
106
-            email_notification: str,
104
+            password: str = None,
105
+            public_name: str = None,
106
+            timezone: str = None,
107
+            profile: str = None,
108
+            email_notification: bool = True,
107 109
     ) -> None:
108 110
         self.email = email
109
-        self.password = password
110
-        self.public_name = public_name
111
-        self.timezone = timezone
112
-        self.profile = profile
111
+        # INFO - G.M - 2018-08-16 - cleartext password, default value
112
+        # is auto-generated.
113
+        self.password = password or password_generator()
114
+        self.public_name = public_name or None
115
+        self.timezone = timezone or ''
116
+        self.profile = profile or Group.TIM_USER_GROUPNAME
113 117
         self.email_notification = email_notification
114 118
 
115 119
 

+ 361 - 0
backend/tracim_backend/tests/functional/test_user.py Прегледај датотеку

@@ -4,6 +4,7 @@ Tests for /api/v2/users subpath endpoints.
4 4
 """
5 5
 from time import sleep
6 6
 import pytest
7
+import requests
7 8
 import transaction
8 9
 
9 10
 from tracim_backend import models
@@ -2422,6 +2423,7 @@ class TestUserWorkspaceEndpoint(FunctionalTest):
2422 2423
         assert sidebar_entry['hexcolor'] == "#ad4cf9"
2423 2424
         assert sidebar_entry['fa_icon'] == "comments-o"
2424 2425
 
2426
+
2425 2427
     def test_api__get_user_workspaces__err_403__unallowed_user(self):
2426 2428
         """
2427 2429
         Check obtain all workspaces reachables for one user
@@ -2636,6 +2638,303 @@ class TestUserEndpoint(FunctionalTest):
2636 2638
             status=403
2637 2639
         )
2638 2640
 
2641
+    def test_api__create_user__ok_200__full_admin(self):
2642
+        self.testapp.authorization = (
2643
+            'Basic',
2644
+            (
2645
+                'admin@admin.admin',
2646
+                'admin@admin.admin'
2647
+            )
2648
+        )
2649
+        params = {
2650
+            'email': 'test@test.test',
2651
+            'password': 'mysuperpassword',
2652
+            'profile': 'users',
2653
+            'timezone': 'Europe/Paris',
2654
+            'public_name': 'test user',
2655
+            'email_notification': False,
2656
+        }
2657
+        res = self.testapp.post_json(
2658
+            '/api/v2/users',
2659
+            status=200,
2660
+            params=params,
2661
+        )
2662
+        res = res.json_body
2663
+        assert res['user_id']
2664
+        user_id = res['user_id']
2665
+        assert res['created']
2666
+        assert res['is_active'] is True
2667
+        assert res['profile'] == 'users'
2668
+        assert res['email'] == 'test@test.test'
2669
+        assert res['public_name'] == 'test user'
2670
+        assert res['timezone'] == 'Europe/Paris'
2671
+
2672
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2673
+        admin = dbsession.query(models.User) \
2674
+            .filter(models.User.email == 'admin@admin.admin') \
2675
+            .one()
2676
+        uapi = UserApi(
2677
+            current_user=admin,
2678
+            session=dbsession,
2679
+            config=self.app_config,
2680
+        )
2681
+        user = uapi.get_one(user_id)
2682
+        assert user.email == 'test@test.test'
2683
+        assert user.validate_password('mysuperpassword')
2684
+
2685
+    def test_api__create_user__ok_200__limited_admin(self):
2686
+        self.testapp.authorization = (
2687
+            'Basic',
2688
+            (
2689
+                'admin@admin.admin',
2690
+                'admin@admin.admin'
2691
+            )
2692
+        )
2693
+        params = {
2694
+            'email': 'test@test.test',
2695
+            'email_notification': False,
2696
+        }
2697
+        res = self.testapp.post_json(
2698
+            '/api/v2/users',
2699
+            status=200,
2700
+            params=params,
2701
+        )
2702
+        res = res.json_body
2703
+        assert res['user_id']
2704
+        user_id = res['user_id']
2705
+        assert res['created']
2706
+        assert res['is_active'] is True
2707
+        assert res['profile'] == 'users'
2708
+        assert res['email'] == 'test@test.test'
2709
+        assert res['public_name'] == 'test'
2710
+        assert res['timezone'] == ''
2711
+
2712
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2713
+        admin = dbsession.query(models.User) \
2714
+            .filter(models.User.email == 'admin@admin.admin') \
2715
+            .one()
2716
+        uapi = UserApi(
2717
+            current_user=admin,
2718
+            session=dbsession,
2719
+            config=self.app_config,
2720
+        )
2721
+        user = uapi.get_one(user_id)
2722
+        assert user.email == 'test@test.test'
2723
+        assert user.password
2724
+
2725
+    def test_api__create_user__err_400__email_already_in_db(self):
2726
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2727
+        admin = dbsession.query(models.User) \
2728
+            .filter(models.User.email == 'admin@admin.admin') \
2729
+            .one()
2730
+        uapi = UserApi(
2731
+            current_user=admin,
2732
+            session=dbsession,
2733
+            config=self.app_config,
2734
+        )
2735
+        gapi = GroupApi(
2736
+            current_user=admin,
2737
+            session=dbsession,
2738
+            config=self.app_config,
2739
+        )
2740
+        groups = [gapi.get_one_with_name('users')]
2741
+        test_user = uapi.create_user(
2742
+            email='test@test.test',
2743
+            password='pass',
2744
+            name='bob',
2745
+            groups=groups,
2746
+            timezone='Europe/Paris',
2747
+            do_save=True,
2748
+            do_notify=False,
2749
+        )
2750
+        uapi.save(test_user)
2751
+        transaction.commit()
2752
+        self.testapp.authorization = (
2753
+            'Basic',
2754
+            (
2755
+                'admin@admin.admin',
2756
+                'admin@admin.admin'
2757
+            )
2758
+        )
2759
+        params = {
2760
+            'email': 'test@test.test',
2761
+            'password': 'mysuperpassword',
2762
+            'profile': 'users',
2763
+            'timezone': 'Europe/Paris',
2764
+            'public_name': 'test user',
2765
+            'email_notification': False,
2766
+        }
2767
+        res = self.testapp.post_json(
2768
+            '/api/v2/users',
2769
+            status=400,
2770
+            params=params,
2771
+        )
2772
+
2773
+    def test_api__create_user__err_403__other_user(self):
2774
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2775
+        admin = dbsession.query(models.User) \
2776
+            .filter(models.User.email == 'admin@admin.admin') \
2777
+            .one()
2778
+        uapi = UserApi(
2779
+            current_user=admin,
2780
+            session=dbsession,
2781
+            config=self.app_config,
2782
+        )
2783
+        gapi = GroupApi(
2784
+            current_user=admin,
2785
+            session=dbsession,
2786
+            config=self.app_config,
2787
+        )
2788
+        groups = [gapi.get_one_with_name('users')]
2789
+        test_user = uapi.create_user(
2790
+            email='test@test.test',
2791
+            password='pass',
2792
+            name='bob',
2793
+            groups=groups,
2794
+            timezone='Europe/Paris',
2795
+            do_save=True,
2796
+            do_notify=False,
2797
+        )
2798
+        uapi.save(test_user)
2799
+        transaction.commit()
2800
+        self.testapp.authorization = (
2801
+            'Basic',
2802
+            (
2803
+                'test@test.test',
2804
+                'pass',
2805
+            )
2806
+        )
2807
+        params = {
2808
+            'email': 'test2@test2.test2',
2809
+            'password': 'mysuperpassword',
2810
+            'profile': 'users',
2811
+            'timezone': 'Europe/Paris',
2812
+            'public_name': 'test user',
2813
+            'email_notification': False,
2814
+        }
2815
+        res = self.testapp.post_json(
2816
+            '/api/v2/users',
2817
+            status=403,
2818
+            params=params,
2819
+        )
2820
+
2821
+
2822
+class TestUserWithNotificationEndpoint(FunctionalTest):
2823
+    """
2824
+    Tests for POST /api/v2/users/{user_id}
2825
+    """
2826
+    config_section = 'functional_test_with_mail_test_sync'
2827
+
2828
+    def test_api__create_user__ok_200__full_admin_with_notif(self):
2829
+        requests.delete('http://127.0.0.1:8025/api/v1/messages')
2830
+        self.testapp.authorization = (
2831
+            'Basic',
2832
+            (
2833
+                'admin@admin.admin',
2834
+                'admin@admin.admin'
2835
+            )
2836
+        )
2837
+        params = {
2838
+            'email': 'test@test.test',
2839
+            'password': 'mysuperpassword',
2840
+            'profile': 'users',
2841
+            'timezone': 'Europe/Paris',
2842
+            'public_name': 'test user',
2843
+            'email_notification': True,
2844
+        }
2845
+        res = self.testapp.post_json(
2846
+            '/api/v2/users',
2847
+            status=200,
2848
+            params=params,
2849
+        )
2850
+        res = res.json_body
2851
+        assert res['user_id']
2852
+        user_id = res['user_id']
2853
+        assert res['created']
2854
+        assert res['is_active'] is True
2855
+        assert res['profile'] == 'users'
2856
+        assert res['email'] == 'test@test.test'
2857
+        assert res['public_name'] == 'test user'
2858
+        assert res['timezone'] == 'Europe/Paris'
2859
+
2860
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2861
+        admin = dbsession.query(models.User) \
2862
+            .filter(models.User.email == 'admin@admin.admin') \
2863
+            .one()
2864
+        uapi = UserApi(
2865
+            current_user=admin,
2866
+            session=dbsession,
2867
+            config=self.app_config,
2868
+        )
2869
+        user = uapi.get_one(user_id)
2870
+        assert user.email == 'test@test.test'
2871
+        assert user.validate_password('mysuperpassword')
2872
+
2873
+        # check mail received
2874
+        response = requests.get('http://127.0.0.1:8025/api/v1/messages')
2875
+        response = response.json()
2876
+        assert len(response) == 1
2877
+        headers = response[0]['Content']['Headers']
2878
+        assert headers['From'][0] == 'Tracim Notifications <test_user_from+0@localhost>'  # nopep8
2879
+        assert headers['To'][0] == 'test user <test@test.test>'
2880
+        assert headers['Subject'][0] == '[TRACIM] Created account'
2881
+
2882
+        # TODO - G.M - 2018-08-02 - Place cleanup outside of the test
2883
+        requests.delete('http://127.0.0.1:8025/api/v1/messages')
2884
+
2885
+    def test_api__create_user__ok_200__limited_admin_with_notif(self):
2886
+        requests.delete('http://127.0.0.1:8025/api/v1/messages')
2887
+        self.testapp.authorization = (
2888
+            'Basic',
2889
+            (
2890
+                'admin@admin.admin',
2891
+                'admin@admin.admin'
2892
+            )
2893
+        )
2894
+        params = {
2895
+            'email': 'test@test.test',
2896
+            'email_notification': True,
2897
+        }
2898
+        res = self.testapp.post_json(
2899
+            '/api/v2/users',
2900
+            status=200,
2901
+            params=params,
2902
+        )
2903
+        res = res.json_body
2904
+        assert res['user_id']
2905
+        user_id = res['user_id']
2906
+        assert res['created']
2907
+        assert res['is_active'] is True
2908
+        assert res['profile'] == 'users'
2909
+        assert res['email'] == 'test@test.test'
2910
+        assert res['public_name'] == 'test'
2911
+        assert res['timezone'] == ''
2912
+
2913
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
2914
+        admin = dbsession.query(models.User) \
2915
+            .filter(models.User.email == 'admin@admin.admin') \
2916
+            .one()
2917
+        uapi = UserApi(
2918
+            current_user=admin,
2919
+            session=dbsession,
2920
+            config=self.app_config,
2921
+        )
2922
+        user = uapi.get_one(user_id)
2923
+        assert user.email == 'test@test.test'
2924
+        assert user.password
2925
+
2926
+        # check mail received
2927
+        response = requests.get('http://127.0.0.1:8025/api/v1/messages')
2928
+        response = response.json()
2929
+        assert len(response) == 1
2930
+        headers = response[0]['Content']['Headers']
2931
+        assert headers['From'][0] == 'Tracim Notifications <test_user_from+0@localhost>'  # nopep8
2932
+        assert headers['To'][0] == 'test <test@test.test>'
2933
+        assert headers['Subject'][0] == '[TRACIM] Created account'
2934
+
2935
+        # TODO - G.M - 2018-08-02 - Place cleanup outside of the test
2936
+        requests.delete('http://127.0.0.1:8025/api/v1/messages')
2937
+
2639 2938
     def test_api_delete_user__ok_200__admin(self):
2640 2939
         dbsession = get_tm_session(self.session_factory, transaction.manager)
2641 2940
         admin = dbsession.query(models.User) \
@@ -3136,6 +3435,68 @@ class TestSetEmailEndpoint(FunctionalTest):
3136 3435
         res = res.json_body
3137 3436
         assert res['email'] == 'mysuperemail@email.fr'
3138 3437
 
3438
+    def test_api__set_user_email__err_400__admin_same_email(self):
3439
+        dbsession = get_tm_session(self.session_factory, transaction.manager)
3440
+        admin = dbsession.query(models.User) \
3441
+            .filter(models.User.email == 'admin@admin.admin') \
3442
+            .one()
3443
+        uapi = UserApi(
3444
+            current_user=admin,
3445
+            session=dbsession,
3446
+            config=self.app_config,
3447
+        )
3448
+        gapi = GroupApi(
3449
+            current_user=admin,
3450
+            session=dbsession,
3451
+            config=self.app_config,
3452
+        )
3453
+        groups = [gapi.get_one_with_name('users')]
3454
+        test_user = uapi.create_user(
3455
+            email='test@test.test',
3456
+            password='pass',
3457
+            name='bob',
3458
+            groups=groups,
3459
+            timezone='Europe/Paris',
3460
+            do_save=True,
3461
+            do_notify=False,
3462
+        )
3463
+        uapi.save(test_user)
3464
+        transaction.commit()
3465
+        user_id = int(test_user.user_id)
3466
+
3467
+        self.testapp.authorization = (
3468
+            'Basic',
3469
+            (
3470
+                'admin@admin.admin',
3471
+                'admin@admin.admin'
3472
+            )
3473
+        )
3474
+        # check before
3475
+        res = self.testapp.get(
3476
+            '/api/v2/users/{}'.format(user_id),
3477
+            status=200
3478
+        )
3479
+        res = res.json_body
3480
+        assert res['email'] == 'test@test.test'
3481
+
3482
+        # Set password
3483
+        params = {
3484
+            'email': 'admin@admin.admin',
3485
+            'loggedin_user_password': 'admin@admin.admin',
3486
+        }
3487
+        self.testapp.put_json(
3488
+            '/api/v2/users/{}/email'.format(user_id),
3489
+            params=params,
3490
+            status=400,
3491
+        )
3492
+        # Check After
3493
+        res = self.testapp.get(
3494
+            '/api/v2/users/{}'.format(user_id),
3495
+            status=200
3496
+        )
3497
+        res = res.json_body
3498
+        assert res['email'] == 'test@test.test'
3499
+
3139 3500
     def test_api__set_user_email__err_403__admin_wrong_password(self):
3140 3501
         dbsession = get_tm_session(self.session_factory, transaction.manager)
3141 3502
         admin = dbsession.query(models.User) \

+ 33 - 6
backend/tracim_backend/views/core_api/schemas.py Прегледај датотеку

@@ -7,6 +7,7 @@ from marshmallow.validate import Range
7 7
 
8 8
 from tracim_backend.lib.utils.utils import DATETIME_FORMAT
9 9
 from tracim_backend.models.auth import Profile
10
+from tracim_backend.models.auth import Group
10 11
 from tracim_backend.models.contents import GlobalStatus
11 12
 from tracim_backend.models.contents import CONTENT_STATUS
12 13
 from tracim_backend.models.contents import CONTENT_TYPES
@@ -159,12 +160,38 @@ class UserProfileSchema(marshmallow.Schema):
159 160
         return UserProfile(**data)
160 161
 
161 162
 
162
-class UserCreationSchema(
163
-    SetEmailSchema,
164
-    SetPasswordSchema,
165
-    UserInfosSchema,
166
-    UserProfileSchema
167
-):
163
+class UserCreationSchema(marshmallow.Schema):
164
+    email = marshmallow.fields.Email(
165
+        required=True,
166
+        example='suri.cate@algoo.fr'
167
+    )
168
+    password = marshmallow.fields.String(
169
+        example='8QLa$<w',
170
+        required=False,
171
+    )
172
+    profile = marshmallow.fields.String(
173
+        attribute='profile',
174
+        validate=OneOf(Profile._NAME),
175
+        example='managers',
176
+        required=False,
177
+        default=Group.TIM_USER_GROUPNAME
178
+    )
179
+    timezone = marshmallow.fields.String(
180
+        example="Europe/Paris",
181
+        required=False,
182
+        default=''
183
+    )
184
+    public_name = marshmallow.fields.String(
185
+        example='Suri Cate',
186
+        required=False,
187
+        default=None,
188
+    )
189
+    email_notification = marshmallow.fields.Bool(
190
+        example=True,
191
+        required=False,
192
+        default=True,
193
+    )
194
+
168 195
     @post_load
169 196
     def create_user(self, data):
170 197
         return UserCreation(**data)

+ 4 - 1
backend/tracim_backend/views/core_api/user_controller.py Прегледај датотеку

@@ -1,4 +1,5 @@
1 1
 from pyramid.config import Configurator
2
+from tracim_backend.lib.utils.utils import password_generator
2 3
 
3 4
 try:  # Python 3.5+
4 5
     from http import HTTPStatus
@@ -16,6 +17,7 @@ from tracim_backend.views.controllers import Controller
16 17
 from tracim_backend.lib.utils.authorization import require_same_user_or_profile
17 18
 from tracim_backend.lib.utils.authorization import require_profile
18 19
 from tracim_backend.exceptions import WrongUserPassword
20
+from tracim_backend.exceptions import EmailAlreadyExistInDb
19 21
 from tracim_backend.exceptions import PasswordDoNotMatch
20 22
 from tracim_backend.views.core_api.schemas import UserSchema
21 23
 from tracim_backend.views.core_api.schemas import AutocompleteQuerySchema
@@ -120,6 +122,7 @@ class UserController(Controller):
120 122
 
121 123
     @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
122 124
     @hapic.handle_exception(WrongUserPassword, HTTPStatus.FORBIDDEN)
125
+    @hapic.handle_exception(EmailAlreadyExistInDb, HTTPStatus.BAD_REQUEST)
123 126
     @require_same_user_or_profile(Group.TIM_ADMIN)
124 127
     @hapic.input_body(SetEmailSchema())
125 128
     @hapic.input_path(UserIdPathSchema())
@@ -192,8 +195,8 @@ class UserController(Controller):
192 195
         return uapi.get_user_with_context(user)
193 196
 
194 197
     @hapic.with_api_doc(tags=[SWAGGER_TAG__USER_ENDPOINTS])
198
+    @hapic.handle_exception(EmailAlreadyExistInDb, HTTPStatus.BAD_REQUEST)
195 199
     @require_profile(Group.TIM_ADMIN)
196
-    @hapic.input_path(UserIdPathSchema())
197 200
     @hapic.input_body(UserCreationSchema())
198 201
     @hapic.output_body(UserSchema())
199 202
     def create_user(self, context, request: TracimRequest, hapic_data=None):

+ 1 - 1
backend/tracim_backend/views/core_api/workspace_controller.py Прегледај датотеку

@@ -287,7 +287,7 @@ class WorkspaceController(Controller):
287 287
                 # notification for creation
288 288
                 user = uapi.create_user(
289 289
                     email=hapic_data.body.user_email_or_public_name,
290
-                    password= password_generator(),
290
+                    password=password_generator(),
291 291
                     do_notify=True
292 292
                 )  # nopep8
293 293
                 newly_created = True