소스 검색

create user when creating role to an unexisting user

Guénaël Muller 6 년 전
부모
커밋
6d3490519b

+ 8 - 0
tracim/exceptions.py 파일 보기

@@ -147,3 +147,11 @@ class EmptyRawContentNotAllowed(EmptyValueNotAllowed):
147 147
 
148 148
 class RoleDoesNotExist(TracimException):
149 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 파일 보기

@@ -5,7 +5,7 @@ from smtplib import SMTPException
5 5
 import transaction
6 6
 import typing as typing
7 7
 
8
-from tracim.exceptions import NotificationNotSend
8
+from tracim.exceptions import NotificationNotSend, EmailValidationFailed
9 9
 from tracim.lib.mail_notifier.notifier import get_email_manager
10 10
 from sqlalchemy.orm import Session
11 11
 
@@ -17,6 +17,7 @@ from tracim.exceptions import UserDoesNotExist
17 17
 from tracim.exceptions import WrongUserPassword
18 18
 from tracim.exceptions import AuthenticationFailed
19 19
 from tracim.models.context_models import UserInContext
20
+from tracim.models.context_models import TypeUser
20 21
 
21 22
 
22 23
 class UserApi(object):
@@ -94,19 +95,40 @@ class UserApi(object):
94 95
     def get_all(self) -> typing.Iterable[User]:
95 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 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 132
     # Check methods
111 133
 
112 134
     def user_with_email_exists(self, email: str) -> bool:
@@ -136,6 +158,15 @@ class UserApi(object):
136 158
 
137 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 170
     def update(
140 171
             self,
141 172
             user: User,
@@ -149,6 +180,9 @@ class UserApi(object):
149 180
             user.display_name = name
150 181
 
151 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 186
             user.email = email
153 187
 
154 188
         if password is not None:
@@ -200,7 +234,11 @@ class UserApi(object):
200 234
         """Previous create_user method"""
201 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 240
         user.email = email
241
+        user.display_name = email.split('@')[0]
204 242
 
205 243
         for group in groups:
206 244
             user.groups.append(group)

+ 8 - 0
tracim/models/context_models.py 파일 보기

@@ -1,6 +1,7 @@
1 1
 # coding=utf-8
2 2
 import typing
3 3
 from datetime import datetime
4
+from enum import Enum
4 5
 
5 6
 from slugify import slugify
6 7
 from sqlalchemy.orm import Session
@@ -173,6 +174,13 @@ class TextBasedContentUpdate(object):
173 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 184
 class UserInContext(object):
177 185
     """
178 186
     Interface to get User data and User data related to context.

+ 1 - 0
tracim/tests/__init__.py 파일 보기

@@ -68,6 +68,7 @@ class FunctionalTest(unittest.TestCase):
68 68
             'depot_storage_dir': '/tmp/test/depot',
69 69
             'depot_storage_name': 'test',
70 70
             'preview_cache_dir': '/tmp/test/preview_cache',
71
+            'email.notification.activated': 'false',
71 72
 
72 73
         }
73 74
         hapic.reset_context()

+ 2 - 2
tracim/tests/functional/test_workspaces.py 파일 보기

@@ -508,7 +508,7 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
508 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 513
         Create workspace member role
514 514
         :return:
@@ -528,7 +528,7 @@ class TestWorkspaceMembersEndpoint(FunctionalTest):
528 528
         }
529 529
         res = self.testapp.post_json(
530 530
             '/api/v2/workspaces/1/members',
531
-            status=400,
531
+            status=200,
532 532
             params=params,
533 533
         )
534 534
 

+ 1 - 1
tracim/tests/library/test_user_api.py 파일 보기

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

+ 18 - 10
tracim/views/core_api/workspace_controller.py 파일 보기

@@ -24,6 +24,8 @@ from tracim.models.data import ActionDescription
24 24
 from tracim.models.context_models import UserRoleWorkspaceInContext
25 25
 from tracim.models.context_models import ContentInContext
26 26
 from tracim.exceptions import EmptyLabelNotAllowed
27
+from tracim.exceptions import EmailValidationFailed
28
+from tracim.exceptions import UserCreationFailed
27 29
 from tracim.exceptions import UserDoesNotExist
28 30
 from tracim.exceptions import WorkspacesDoNotMatch
29 31
 from tracim.views.controllers import Controller
@@ -170,6 +172,7 @@ class WorkspaceController(Controller):
170 172
         return rapi.get_user_role_workspace_with_context(role)
171 173
 
172 174
     @hapic.with_api_doc(tags=[WORKSPACE_ENDPOINTS_TAG])
175
+    @hapic.handle_exception(UserCreationFailed, HTTPStatus.BAD_REQUEST)
173 176
     @require_workspace_role(UserRoleInWorkspace.WORKSPACE_MANAGER)
174 177
     @hapic.input_path(WorkspaceIdPathSchema())
175 178
     @hapic.input_body(WorkspaceMemberInviteSchema())
@@ -194,17 +197,22 @@ class WorkspaceController(Controller):
194 197
             session=request.dbsession,
195 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 216
         role = rapi.create_one(
209 217
             user=user,
210 218
             workspace=request.current_workspace,