Sfoglia il codice sorgente

create user when creating role to an unexisting user

Guénaël Muller 6 anni fa
parent
commit
6d3490519b

+ 8 - 0
tracim/exceptions.py Vedi File

147
 
147
 
148
 class RoleDoesNotExist(TracimException):
148
 class RoleDoesNotExist(TracimException):
149
     pass
149
     pass
150
+
151
+
152
+class EmailValidationFailed(TracimException):
153
+    pass
154
+
155
+
156
+class UserCreationFailed(TracimException):
157
+    pass

+ 49 - 11
tracim/lib/core/user.py Vedi File

5
 import transaction
5
 import transaction
6
 import typing as typing
6
 import typing as typing
7
 
7
 
8
-from tracim.exceptions import NotificationNotSend
8
+from tracim.exceptions import NotificationNotSend, EmailValidationFailed
9
 from tracim.lib.mail_notifier.notifier import get_email_manager
9
 from tracim.lib.mail_notifier.notifier import get_email_manager
10
 from sqlalchemy.orm import Session
10
 from sqlalchemy.orm import Session
11
 
11
 
17
 from tracim.exceptions import WrongUserPassword
17
 from tracim.exceptions import WrongUserPassword
18
 from tracim.exceptions import AuthenticationFailed
18
 from tracim.exceptions import AuthenticationFailed
19
 from tracim.models.context_models import UserInContext
19
 from tracim.models.context_models import UserInContext
20
+from tracim.models.context_models import TypeUser
20
 
21
 
21
 
22
 
22
 class UserApi(object):
23
 class UserApi(object):
94
     def get_all(self) -> typing.Iterable[User]:
95
     def get_all(self) -> typing.Iterable[User]:
95
         return self._session.query(User).order_by(User.display_name).all()
96
         return self._session.query(User).order_by(User.display_name).all()
96
 
97
 
97
-    def find_one(self, user_email_or_public_name: str) -> User:
98
+    def find(
99
+            self,
100
+            user_id: int=None,
101
+            email: str=None,
102
+            public_name: str=None
103
+    ) -> typing.Tuple[TypeUser, User]:
104
+        """
105
+        Find existing user from all theses params.
106
+        Check is made in this order: user_id, email, public_name
107
+        If no user found raise UserDoesNotExist exception
108
+        """
98
         user = None
109
         user = None
99
-        try:
100
-            user = self.get_one_by_email(email=user_email_or_public_name)
101
-        except UserDoesNotExist:
102
-            # INFO - G.M - 2018-07-183 - we discard this exception in order
103
-            # allow secondary check (public_name)
104
-            pass
105
 
110
 
106
-        if not user:
107
-            user = self.get_one_by_public_name(user_email_or_public_name)
111
+        if user_id:
112
+            try:
113
+                user = self.get_one(user_id)
114
+                return TypeUser.USER_ID, user
115
+            except UserDoesNotExist:
116
+                pass
117
+        if email:
118
+            try:
119
+                user = self.get_one_by_email(email)
120
+                return TypeUser.EMAIL, user
121
+            except UserDoesNotExist:
122
+                pass
123
+        if public_name:
124
+            try:
125
+                user = self.get_one_by_public_name(public_name)
126
+                return TypeUser.PUBLIC_NAME, user
127
+            except UserDoesNotExist:
128
+                pass
129
+
130
+        raise UserDoesNotExist('User not found with any of given params.')
108
 
131
 
109
-        return user
110
     # Check methods
132
     # Check methods
111
 
133
 
112
     def user_with_email_exists(self, email: str) -> bool:
134
     def user_with_email_exists(self, email: str) -> bool:
136
 
158
 
137
     # Actions
159
     # Actions
138
 
160
 
161
+    def _check_email(self, email: str) -> bool:
162
+        # TODO - G.M - 2018-07-05 - find a better way to check email
163
+        if not email:
164
+            return False
165
+        email = email.split('@')
166
+        if len(email) != 2:
167
+            return False
168
+        return True
169
+
139
     def update(
170
     def update(
140
             self,
171
             self,
141
             user: User,
172
             user: User,
149
             user.display_name = name
180
             user.display_name = name
150
 
181
 
151
         if email is not None:
182
         if email is not None:
183
+            email_exist = self._check_email(email)
184
+            if not email_exist:
185
+                raise EmailValidationFailed('Email given form {} is uncorrect'.format(email))  # nopep8
152
             user.email = email
186
             user.email = email
153
 
187
 
154
         if password is not None:
188
         if password is not None:
200
         """Previous create_user method"""
234
         """Previous create_user method"""
201
         user = User()
235
         user = User()
202
 
236
 
237
+        email_exist = self._check_email(email)
238
+        if not email_exist:
239
+            raise EmailValidationFailed('Email given form {} is uncorrect'.format(email))  # nopep8
203
         user.email = email
240
         user.email = email
241
+        user.display_name = email.split('@')[0]
204
 
242
 
205
         for group in groups:
243
         for group in groups:
206
             user.groups.append(group)
244
             user.groups.append(group)

+ 8 - 0
tracim/models/context_models.py Vedi File

1
 # coding=utf-8
1
 # coding=utf-8
2
 import typing
2
 import typing
3
 from datetime import datetime
3
 from datetime import datetime
4
+from enum import Enum
4
 
5
 
5
 from slugify import slugify
6
 from slugify import slugify
6
 from sqlalchemy.orm import Session
7
 from sqlalchemy.orm import Session
173
         self.raw_content = raw_content
174
         self.raw_content = raw_content
174
 
175
 
175
 
176
 
177
+class TypeUser(Enum):
178
+    """Params used to find user"""
179
+    USER_ID = 'found_id'
180
+    EMAIL = 'found_email'
181
+    PUBLIC_NAME = 'found_public_name'
182
+
183
+
176
 class UserInContext(object):
184
 class UserInContext(object):
177
     """
185
     """
178
     Interface to get User data and User data related to context.
186
     Interface to get User data and User data related to context.

+ 1 - 0
tracim/tests/__init__.py Vedi File

68
             'depot_storage_dir': '/tmp/test/depot',
68
             'depot_storage_dir': '/tmp/test/depot',
69
             'depot_storage_name': 'test',
69
             'depot_storage_name': 'test',
70
             'preview_cache_dir': '/tmp/test/preview_cache',
70
             'preview_cache_dir': '/tmp/test/preview_cache',
71
+            'email.notification.activated': 'false',
71
 
72
 
72
         }
73
         }
73
         hapic.reset_context()
74
         hapic.reset_context()

+ 2 - 2
tracim/tests/functional/test_workspaces.py Vedi File

508
             params=params,
508
             params=params,
509
         )
509
         )
510
 
510
 
511
-    def test_api__create_workspace_member_role__err_400__wrong_user_email_or_public_name(self):  # nopep8
511
+    def test_api__create_workspace_member_role__ok_200__new_user(self):  # nopep8
512
         """
512
         """
513
         Create workspace member role
513
         Create workspace member role
514
         :return:
514
         :return:
528
         }
528
         }
529
         res = self.testapp.post_json(
529
         res = self.testapp.post_json(
530
             '/api/v2/workspaces/1/members',
530
             '/api/v2/workspaces/1/members',
531
-            status=400,
531
+            status=200,
532
             params=params,
532
             params=params,
533
         )
533
         )
534
 
534
 

+ 1 - 1
tracim/tests/library/test_user_api.py Vedi File

22
         )
22
         )
23
         u = api.create_minimal_user('bob@bob')
23
         u = api.create_minimal_user('bob@bob')
24
         assert u.email == 'bob@bob'
24
         assert u.email == 'bob@bob'
25
-        assert u.display_name is None
25
+        assert u.display_name == 'bob'
26
 
26
 
27
     def test_unit__create_minimal_user_and_update__ok__nominal_case(self):
27
     def test_unit__create_minimal_user_and_update__ok__nominal_case(self):
28
         api = UserApi(
28
         api = UserApi(

+ 18 - 10
tracim/views/core_api/workspace_controller.py Vedi File

24
 from tracim.models.context_models import UserRoleWorkspaceInContext
24
 from tracim.models.context_models import UserRoleWorkspaceInContext
25
 from tracim.models.context_models import ContentInContext
25
 from tracim.models.context_models import ContentInContext
26
 from tracim.exceptions import EmptyLabelNotAllowed
26
 from tracim.exceptions import EmptyLabelNotAllowed
27
+from tracim.exceptions import EmailValidationFailed
28
+from tracim.exceptions import UserCreationFailed
27
 from tracim.exceptions import UserDoesNotExist
29
 from tracim.exceptions import UserDoesNotExist
28
 from tracim.exceptions import WorkspacesDoNotMatch
30
 from tracim.exceptions import WorkspacesDoNotMatch
29
 from tracim.views.controllers import Controller
31
 from tracim.views.controllers import Controller
170
         return rapi.get_user_role_workspace_with_context(role)
172
         return rapi.get_user_role_workspace_with_context(role)
171
 
173
 
172
     @hapic.with_api_doc(tags=[WORKSPACE_ENDPOINTS_TAG])
174
     @hapic.with_api_doc(tags=[WORKSPACE_ENDPOINTS_TAG])
175
+    @hapic.handle_exception(UserCreationFailed, HTTPStatus.BAD_REQUEST)
173
     @require_workspace_role(UserRoleInWorkspace.WORKSPACE_MANAGER)
176
     @require_workspace_role(UserRoleInWorkspace.WORKSPACE_MANAGER)
174
     @hapic.input_path(WorkspaceIdPathSchema())
177
     @hapic.input_path(WorkspaceIdPathSchema())
175
     @hapic.input_body(WorkspaceMemberInviteSchema())
178
     @hapic.input_body(WorkspaceMemberInviteSchema())
194
             session=request.dbsession,
197
             session=request.dbsession,
195
             config=app_config,
198
             config=app_config,
196
         )
199
         )
197
-        if hapic_data.body.user_id is not None:
198
-            user = uapi.get_one(user_id=hapic_data.body.user_id)
199
-        elif hapic_data.body.user_email_or_public_name:
200
-            user = uapi.find_one(
201
-                user_email_or_public_name=hapic_data.body.user_email_or_public_name  # nopep8
202
-            )
203
-        else:
204
-            raise UserDoesNotExist(
205
-                'user_id or user_email_or_public_name should have '
206
-                'valid value.'
200
+        try:
201
+            _, user = uapi.find(
202
+                user_id=hapic_data.body.user_id,
203
+                email=hapic_data.body.user_email_or_public_name,
204
+                public_name=hapic_data.body.user_email_or_public_name
207
             )
205
             )
206
+        except UserDoesNotExist:
207
+            try:
208
+                # TODO - G.M - 2018-07-05 - [UserCreation] Reenable email
209
+                # notification for creation
210
+                user = uapi.create_user(
211
+                    hapic_data.body.user_email_or_public_name,
212
+                    do_notify=False
213
+                )  # nopep8
214
+            except EmailValidationFailed:
215
+                raise UserCreationFailed('no valid mail given')
208
         role = rapi.create_one(
216
         role = rapi.create_one(
209
             user=user,
217
             user=user,
210
             workspace=request.current_workspace,
218
             workspace=request.current_workspace,