瀏覽代碼

better login view and better user_api related : authenticate_user method

Guénaël Muller 7 年之前
父節點
當前提交
eb3b6c3067
共有 3 個文件被更改,包括 50 次插入32 次删除
  1. 5 1
      tracim/exceptions.py
  2. 33 13
      tracim/lib/core/user.py
  3. 12 18
      tracim/views/core_api/session_controller.py

+ 5 - 1
tracim/exceptions.py 查看文件

85
     pass
85
     pass
86
 
86
 
87
 
87
 
88
-class LoginFailed(TracimException):
88
+class AuthenticationFailed(TracimException):
89
+    pass
90
+
91
+
92
+class BadUserPassword(TracimException):
89
     pass
93
     pass

+ 33 - 13
tracim/lib/core/user.py 查看文件

5
 import typing as typing
5
 import typing as typing
6
 
6
 
7
 from tracim.models.auth import User
7
 from tracim.models.auth import User
8
+from sqlalchemy.orm.exc import NoResultFound
9
+from tracim.exceptions import BadUserPassword
10
+from tracim.exceptions import AuthenticationFailed
8
 
11
 
9
 
12
 
10
 class UserApi(object):
13
 class UserApi(object):
14
         self._user = current_user
17
         self._user = current_user
15
         self._config = config
18
         self._config = config
16
 
19
 
17
-    def get_all(self):
18
-        return self._session.query(User).order_by(User.display_name).all()
19
-
20
     def _base_query(self):
20
     def _base_query(self):
21
         return self._session.query(User)
21
         return self._session.query(User)
22
 
22
 
23
-    def get_one(self, user_id: int):
23
+    def get_one(self, user_id: int) -> User:
24
         return self._base_query().filter(User.user_id==user_id).one()
24
         return self._base_query().filter(User.user_id==user_id).one()
25
 
25
 
26
-    def get_one_by_email(self, email: str):
26
+    def get_one_by_email(self, email: str) -> User:
27
         return self._base_query().filter(User.email==email).one()
27
         return self._base_query().filter(User.email==email).one()
28
 
28
 
29
     def get_one_by_id(self, id: int) -> User:
29
     def get_one_by_id(self, id: int) -> User:
30
         return self._base_query().filter(User.user_id==id).one()
30
         return self._base_query().filter(User.user_id==id).one()
31
 
31
 
32
+    def get_all(self) -> typing.Iterable[User]:
33
+        return self._session.query(User).order_by(User.display_name).all()
34
+
35
+    def user_with_email_exists(self, email: str):
36
+        try:
37
+            self.get_one_by_email(email)
38
+            return True
39
+        # TODO - G.M - 09-04-2018 - Better exception
40
+        except:
41
+            return False
42
+
43
+    def authenticate_user(self, email, password) -> User:
44
+        """
45
+        Authenticate user with email and password, raise AuthenticationFailed
46
+        if uncorrect.
47
+        :param email: email of the user
48
+        :param password: cleartext password of the user
49
+        :return: User who was authenticated.
50
+        """
51
+        try:
52
+            user = self.get_one_by_email(email)
53
+            if user.validate_password(password):
54
+                return user
55
+            else:
56
+                raise BadUserPassword()
57
+        except (BadUserPassword, NoResultFound):
58
+            raise AuthenticationFailed
59
+
32
     def update(
60
     def update(
33
             self,
61
             self,
34
             user: User,
62
             user: User,
48
         if do_save:
76
         if do_save:
49
             self.save(user)
77
             self.save(user)
50
 
78
 
51
-    def user_with_email_exists(self, email: str):
52
-        try:
53
-            self.get_one_by_email(email)
54
-            return True
55
-        # TODO - G.M - 09-04-2018 - Better exception
56
-        except:
57
-            return False
58
-
59
     def create_user(self, email=None, groups=[], save_now=False) -> User:
79
     def create_user(self, email=None, groups=[], save_now=False) -> User:
60
         user = User()
80
         user = User()
61
 
81
 

+ 12 - 18
tracim/views/core_api/session_controller.py 查看文件

14
 from pyramid.config import Configurator
14
 from pyramid.config import Configurator
15
 
15
 
16
 from tracim.views import BASE_API_V2
16
 from tracim.views import BASE_API_V2
17
-from tracim.views.core_api.schemas import UserSchema, NoContentSchema
17
+from tracim.views.core_api.schemas import UserSchema
18
+from tracim.views.core_api.schemas import NoContentSchema
19
+
18
 from tracim.views.core_api.schemas import LoginOutputHeaders
20
 from tracim.views.core_api.schemas import LoginOutputHeaders
19
 from tracim.views.core_api.schemas import BasicAuthSchema
21
 from tracim.views.core_api.schemas import BasicAuthSchema
20
-from tracim.exceptions import NotAuthentificated, LoginFailed
22
+from tracim.exceptions import NotAuthentificated
23
+from tracim.exceptions import AuthenticationFailed
21
 
24
 
22
 try:  # Python 3.5+
25
 try:  # Python 3.5+
23
     from http import HTTPStatus
26
     from http import HTTPStatus
30
     @hapic.with_api_doc()
33
     @hapic.with_api_doc()
31
     @hapic.input_headers(LoginOutputHeaders())
34
     @hapic.input_headers(LoginOutputHeaders())
32
     @hapic.input_body(BasicAuthSchema())
35
     @hapic.input_body(BasicAuthSchema())
33
-    @hapic.handle_exception(LoginFailed, http_code=HTTPStatus.BAD_REQUEST)
36
+    @hapic.handle_exception(AuthenticationFailed, http_code=HTTPStatus.BAD_REQUEST)
34
     # TODO - G.M - 17-04-2018 - fix output header ?
37
     # TODO - G.M - 17-04-2018 - fix output header ?
35
     # @hapic.output_headers()
38
     # @hapic.output_headers()
36
     @hapic.output_body(
39
     @hapic.output_body(
44
         email = request.json_body['email']
47
         email = request.json_body['email']
45
         password = request.json_body['password']
48
         password = request.json_body['password']
46
         app_config = request.registry.settings['CFG']
49
         app_config = request.registry.settings['CFG']
47
-        try:
48
-            uapi = UserApi(
49
-                None,
50
-                session=request.dbsession,
51
-                config=app_config,
52
-            )
53
-            user = uapi.get_one_by_email(email)
54
-            valid_password = user.validate_password(password)
55
-            if not valid_password:
56
-                # Bad password
57
-                raise LoginFailed('Bad Credentials')
58
-        except NoResultFound:
59
-            # User does not exist
60
-            raise LoginFailed('Bad Credentials')
61
-        return
50
+        uapi = UserApi(
51
+            None,
52
+            session=request.dbsession,
53
+            config=app_config,
54
+        )
55
+        return uapi.authenticate_user(email, password)
62
 
56
 
63
     @hapic.with_api_doc()
57
     @hapic.with_api_doc()
64
     @hapic.output_body(
58
     @hapic.output_body(