Completed
Push — master ( fe6d7a...5e9dbb )
by
unknown
02:04
created

tracim.command.user.UserCommand._proceed_user()   B

Complexity

Conditions 4

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 15
dl 0
loc 28
rs 8.5806
c 0
b 0
f 0
cc 4
nop 2
1
# -*- coding: utf-8 -*-
2
import transaction
3
from sqlalchemy.exc import IntegrityError
4
5
from tracim import CFG
6
from tracim.command import AppContextCommand
7
from tracim.command import Extender
8
#from tracim.lib.auth.ldap import LDAPAuth
9
#from tracim.lib.daemons import DaemonsManager
10
#from tracim.lib.daemons import RadicaleDaemon
11
#from tracim.lib.email import get_email_manager
12
from tracim.exceptions import AlreadyExistError
13
from tracim.exceptions import CommandAbortedError
14
from tracim.lib.core.group import GroupApi
15
from tracim.lib.core.user import UserApi
16
from tracim.models import User
17
18
19
class UserCommand(AppContextCommand):
20
21
    ACTION_CREATE = 'create'
22
    ACTION_UPDATE = 'update'
23
24
    action = NotImplemented
25
26
    def get_description(self):
27
        return '''Create or update user.'''
28
29
    def get_parser(self, prog_name):
30
        parser = super().get_parser(prog_name)
31
32
        parser.add_argument(
33
            "-l",
34
            "--login",
35
            help='User login (email)',
36
            dest='login',
37
            required=True
38
        )
39
40
        parser.add_argument(
41
            "-p",
42
            "--password",
43
            help='User password',
44
            dest='password',
45
            required=False,
46
            default=None
47
        )
48
49
        parser.add_argument(
50
            "-g",
51
            "--add-to-group",
52
            help='Add user to group',
53
            dest='add_to_group',
54
            nargs='*',
55
            action=Extender,
56
            default=[],
57
        )
58
59
        parser.add_argument(
60
            "-rmg",
61
            "--remove-from-group",
62
            help='Remove user from group',
63
            dest='remove_from_group',
64
            nargs='*',
65
            action=Extender,
66
            default=[],
67
        )
68
69
        parser.add_argument(
70
            "--send-email",
71
            help='Send mail to user',
72
            dest='send_email',
73
            required=False,
74
            action='store_true',
75
            default=False,
76
        )
77
78
        return parser
79
80
    def _user_exist(self, login):
81
        return self._user_api.user_with_email_exists(login)
82
83
    def _get_group(self, name):
84
        return self._group_api.get_one_with_name(name)
85
86
    def _add_user_to_named_group(self, user, group_name):
87
        group = self._get_group(group_name)
88
        if user not in group.users:
89
            group.users.append(user)
90
        self._session.flush()
91
92
    def _remove_user_from_named_group(self, user, group_name):
93
        group = self._get_group(group_name)
94
        if user in group.users:
95
            group.users.remove(user)
96
        self._session.flush()
97
98
    def _create_user(self, login, password, **kwargs):
99
        if not password:
100
            if self._password_required():
101
                raise CommandAbortedError("You must provide -p/--password parameter")
102
            password = ''
103
104
        try:
105
            user =self._user_api.create_user(email=login)
106
            user.password = password
107
            self._user_api.save(user)
108
            # TODO - G.M - 04-04-2018 - [Caldav] Check this code
109
            # # We need to enable radicale if it not already done
110
            # daemons = DaemonsManager()
111
            # daemons.run('radicale', RadicaleDaemon)
112
113
            self._user_api.execute_created_user_actions(user)
114
        except IntegrityError:
115
            self._session.rollback()
116
            raise AlreadyExistError()
117
118
        return user
119
120
    def _update_password_for_login(self, login, password):
121
        user = self._user_api.get_one_by_email(login)
122
        user.password = password
123
        self._session.flush()
124
        transaction.commit()
125
126
    def take_app_action(self, parsed_args, app_context):
127
        # TODO - G.M - 05-04-2018 -Refactor this in order
128
        # to not setup object var outside of __init__ .
129
        self._session = app_context['request'].dbsession
130
        self._app_config = app_context['registry'].settings['CFG']
131
        self._user_api = UserApi(
132
            current_user=None,
133
            session=self._session,
134
            config=self._app_config,
135
        )
136
        self._group_api = GroupApi(
137
            current_user=None,
138
            session=self._session,
139
        )
140
        user = self._proceed_user(parsed_args)
141
        self._proceed_groups(user, parsed_args)
142
143
        print("User created/updated")
144
145
    def _proceed_user(self, parsed_args):
146
        self._check_context(parsed_args)
147
148
        if self.action == self.ACTION_CREATE:
149
            try:
150
                user = self._create_user(
151
                    login=parsed_args.login,
152
                    password=parsed_args.password
153
                )
154
            except AlreadyExistError:
155
                raise CommandAbortedError("Error: User already exist (use `user update` command instead)")
156
            # TODO - G.M - 04-04-2018 - [Email] Check this code
157
            # if parsed_args.send_email:
158
            #     email_manager = get_email_manager()
159
            #     email_manager.notify_created_account(
160
            #         user=user,
161
            #         password=parsed_args.password,
162
            #     )
163
164
        else:
165
            if parsed_args.password:
166
                self._update_password_for_login(
167
                    login=parsed_args.login,
168
                    password=parsed_args.password
169
                )
170
            user = self._user_api.get_one_by_email(parsed_args.login)
171
172
        return user
173
174
    def _proceed_groups(self, user, parsed_args):
175
        # User always in "users" group
176
        self._add_user_to_named_group(user, 'users')
177
178
        for group_name in parsed_args.add_to_group:
179
            self._add_user_to_named_group(user, group_name)
180
181
        for group_name in parsed_args.remove_from_group:
182
            self._remove_user_from_named_group(user, group_name)
183
184
    def _password_required(self):
185
        # TODO - G.M - 04-04-2018 - [LDAP] Check this code
186
        # if config.get('auth_type') == LDAPAuth.name:
187
        #     return False
188
        return True
189
190
    def _check_context(self, parsed_args):
191
        # TODO - G.M - 04-04-2018 - [LDAP] Check this code
192
        # if config.get('auth_type') == LDAPAuth.name:
193
        #     auth_instance = config.get('auth_instance')
194
        #     if not auth_instance.ldap_auth.user_exist(parsed_args.login):
195
        #         raise LDAPUserUnknown(
196
        #             "LDAP is enabled and user with login/email \"%s\" not found in LDAP" % parsed_args.login
197
        #         )
198
        pass
199
200
201
class CreateUserCommand(UserCommand):
202
    action = UserCommand.ACTION_CREATE
203
204
205
class UpdateUserCommand(UserCommand):
206
    action = UserCommand.ACTION_UPDATE
207
208
209
class LDAPUserUnknown(CommandAbortedError):
210
    pass
211