root / snf-astakos-app / astakos / im / management / commands / user-modify.py @ 1e361a6d
History | View | Annotate | Download (10.1 kB)
1 | ca96a346 | Giorgos Verigakis | # Copyright 2012 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | df48dd1b | Giorgos Verigakis | #
|
3 | df48dd1b | Giorgos Verigakis | # Redistribution and use in source and binary forms, with or
|
4 | df48dd1b | Giorgos Verigakis | # without modification, are permitted provided that the following
|
5 | df48dd1b | Giorgos Verigakis | # conditions are met:
|
6 | df48dd1b | Giorgos Verigakis | #
|
7 | df48dd1b | Giorgos Verigakis | # 1. Redistributions of source code must retain the above
|
8 | df48dd1b | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
9 | df48dd1b | Giorgos Verigakis | # disclaimer.
|
10 | df48dd1b | Giorgos Verigakis | #
|
11 | df48dd1b | Giorgos Verigakis | # 2. Redistributions in binary form must reproduce the above
|
12 | df48dd1b | Giorgos Verigakis | # copyright notice, this list of conditions and the following
|
13 | df48dd1b | Giorgos Verigakis | # disclaimer in the documentation and/or other materials
|
14 | df48dd1b | Giorgos Verigakis | # provided with the distribution.
|
15 | df48dd1b | Giorgos Verigakis | #
|
16 | df48dd1b | Giorgos Verigakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | df48dd1b | Giorgos Verigakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | df48dd1b | Giorgos Verigakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | df48dd1b | Giorgos Verigakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | df48dd1b | Giorgos Verigakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | df48dd1b | Giorgos Verigakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | df48dd1b | Giorgos Verigakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | df48dd1b | Giorgos Verigakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | df48dd1b | Giorgos Verigakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | df48dd1b | Giorgos Verigakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | df48dd1b | Giorgos Verigakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | df48dd1b | Giorgos Verigakis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | df48dd1b | Giorgos Verigakis | #
|
29 | df48dd1b | Giorgos Verigakis | # The views and conclusions contained in the software and
|
30 | df48dd1b | Giorgos Verigakis | # documentation are those of the authors and should not be
|
31 | df48dd1b | Giorgos Verigakis | # interpreted as representing official policies, either expressed
|
32 | df48dd1b | Giorgos Verigakis | # or implied, of GRNET S.A.
|
33 | df48dd1b | Giorgos Verigakis | |
34 | df48dd1b | Giorgos Verigakis | from optparse import make_option |
35 | df48dd1b | Giorgos Verigakis | |
36 | df48dd1b | Giorgos Verigakis | from django.core.management.base import BaseCommand, CommandError |
37 | c0b26605 | Sofia Papagiannaki | from django.contrib.auth.models import Group |
38 | 0a569195 | Sofia Papagiannaki | from django.core.exceptions import ValidationError |
39 | df48dd1b | Giorgos Verigakis | |
40 | 9a06d96f | Olga Brani | from astakos.im.models import AstakosUser |
41 | 9770ba6c | Giorgos Korfiatis | from astakos.im.functions import (activate, deactivate) |
42 | 764d99c4 | Giorgos Korfiatis | from astakos.im import quotas |
43 | 92359537 | Sofia Papagiannaki | from ._common import remove_user_permission, add_user_permission, is_uuid |
44 | b830f774 | Giorgos Korfiatis | from snf_django.lib.db.transaction import commit_on_success_strict |
45 | 764d99c4 | Giorgos Korfiatis | import string |
46 | df48dd1b | Giorgos Verigakis | |
47 | 5ce3ce4f | Sofia Papagiannaki | |
48 | df48dd1b | Giorgos Verigakis | class Command(BaseCommand): |
49 | 0a569195 | Sofia Papagiannaki | args = "<user ID>"
|
50 | df48dd1b | Giorgos Verigakis | help = "Modify a user's attributes"
|
51 | 5ce3ce4f | Sofia Papagiannaki | |
52 | 9a06d96f | Olga Brani | option_list = BaseCommand.option_list + ( |
53 | df48dd1b | Giorgos Verigakis | make_option('--invitations',
|
54 | 5ce3ce4f | Sofia Papagiannaki | dest='invitations',
|
55 | 5ce3ce4f | Sofia Papagiannaki | metavar='NUM',
|
56 | 5ce3ce4f | Sofia Papagiannaki | help="Update user's invitations"),
|
57 | ebd369d0 | Sofia Papagiannaki | make_option('--level',
|
58 | 5ce3ce4f | Sofia Papagiannaki | dest='level',
|
59 | 5ce3ce4f | Sofia Papagiannaki | metavar='NUM',
|
60 | 5ce3ce4f | Sofia Papagiannaki | help="Update user's level"),
|
61 | df48dd1b | Giorgos Verigakis | make_option('--password',
|
62 | 5ce3ce4f | Sofia Papagiannaki | dest='password',
|
63 | 5ce3ce4f | Sofia Papagiannaki | metavar='PASSWORD',
|
64 | 5ce3ce4f | Sofia Papagiannaki | help="Set user's password"),
|
65 | df48dd1b | Giorgos Verigakis | make_option('--renew-token',
|
66 | 5ce3ce4f | Sofia Papagiannaki | action='store_true',
|
67 | 5ce3ce4f | Sofia Papagiannaki | dest='renew_token',
|
68 | 5ce3ce4f | Sofia Papagiannaki | default=False,
|
69 | 5ce3ce4f | Sofia Papagiannaki | help="Renew the user's token"),
|
70 | cfb15117 | Sofia Papagiannaki | make_option('--renew-password',
|
71 | 5ce3ce4f | Sofia Papagiannaki | action='store_true',
|
72 | 5ce3ce4f | Sofia Papagiannaki | dest='renew_password',
|
73 | 5ce3ce4f | Sofia Papagiannaki | default=False,
|
74 | 5ce3ce4f | Sofia Papagiannaki | help="Renew the user's password"),
|
75 | df48dd1b | Giorgos Verigakis | make_option('--set-admin',
|
76 | 5ce3ce4f | Sofia Papagiannaki | action='store_true',
|
77 | 5ce3ce4f | Sofia Papagiannaki | dest='admin',
|
78 | 5ce3ce4f | Sofia Papagiannaki | default=False,
|
79 | 5ce3ce4f | Sofia Papagiannaki | help="Give user admin rights"),
|
80 | df48dd1b | Giorgos Verigakis | make_option('--set-noadmin',
|
81 | 5ce3ce4f | Sofia Papagiannaki | action='store_true',
|
82 | 5ce3ce4f | Sofia Papagiannaki | dest='noadmin',
|
83 | 5ce3ce4f | Sofia Papagiannaki | default=False,
|
84 | 5ce3ce4f | Sofia Papagiannaki | help="Revoke user's admin rights"),
|
85 | ebd369d0 | Sofia Papagiannaki | make_option('--set-active',
|
86 | 5ce3ce4f | Sofia Papagiannaki | action='store_true',
|
87 | 5ce3ce4f | Sofia Papagiannaki | dest='active',
|
88 | 5ce3ce4f | Sofia Papagiannaki | default=False,
|
89 | 21e0fdad | Giorgos Korfiatis | help="Change user's state to active"),
|
90 | ebd369d0 | Sofia Papagiannaki | make_option('--set-inactive',
|
91 | 5ce3ce4f | Sofia Papagiannaki | action='store_true',
|
92 | 5ce3ce4f | Sofia Papagiannaki | dest='inactive',
|
93 | 5ce3ce4f | Sofia Papagiannaki | default=False,
|
94 | 5ce3ce4f | Sofia Papagiannaki | help="Change user's state to inactive"),
|
95 | 4e30244e | Sofia Papagiannaki | make_option('--add-group',
|
96 | 5ce3ce4f | Sofia Papagiannaki | dest='add-group',
|
97 | 5ce3ce4f | Sofia Papagiannaki | help="Add user group"),
|
98 | 4e30244e | Sofia Papagiannaki | make_option('--delete-group',
|
99 | 5ce3ce4f | Sofia Papagiannaki | dest='delete-group',
|
100 | 5ce3ce4f | Sofia Papagiannaki | help="Delete user group"),
|
101 | 30dc8c1a | Sofia Papagiannaki | make_option('--add-permission',
|
102 | 5ce3ce4f | Sofia Papagiannaki | dest='add-permission',
|
103 | 5ce3ce4f | Sofia Papagiannaki | help="Add user permission"),
|
104 | 30dc8c1a | Sofia Papagiannaki | make_option('--delete-permission',
|
105 | 5ce3ce4f | Sofia Papagiannaki | dest='delete-permission',
|
106 | 5ce3ce4f | Sofia Papagiannaki | help="Delete user permission"),
|
107 | 764d99c4 | Giorgos Korfiatis | make_option('--set-base-quota',
|
108 | 764d99c4 | Giorgos Korfiatis | dest='set_base_quota',
|
109 | 764d99c4 | Giorgos Korfiatis | metavar='<resource> <capacity>',
|
110 | 764d99c4 | Giorgos Korfiatis | nargs=2,
|
111 | 764d99c4 | Giorgos Korfiatis | help=("Set base quota for a specified resource. "
|
112 | 764d99c4 | Giorgos Korfiatis | "The special value 'default' sets the user base "
|
113 | 764d99c4 | Giorgos Korfiatis | "quota to the default value.")
|
114 | 764d99c4 | Giorgos Korfiatis | ), |
115 | 764d99c4 | Giorgos Korfiatis | |
116 | 9a06d96f | Olga Brani | ) |
117 | 9a06d96f | Olga Brani | |
118 | 200b37fb | Giorgos Korfiatis | @commit_on_success_strict()
|
119 | df48dd1b | Giorgos Verigakis | def handle(self, *args, **options): |
120 | df48dd1b | Giorgos Verigakis | if len(args) != 1: |
121 | 0a569195 | Sofia Papagiannaki | raise CommandError("Please provide a user ID") |
122 | 5ce3ce4f | Sofia Papagiannaki | |
123 | 0a569195 | Sofia Papagiannaki | if args[0].isdigit(): |
124 | 92359537 | Sofia Papagiannaki | try:
|
125 | 92359537 | Sofia Papagiannaki | user = AstakosUser.objects.get(id=int(args[0])) |
126 | 92359537 | Sofia Papagiannaki | except AstakosUser.DoesNotExist:
|
127 | 92359537 | Sofia Papagiannaki | raise CommandError("Invalid user ID") |
128 | 92359537 | Sofia Papagiannaki | elif is_uuid(args[0]): |
129 | 92359537 | Sofia Papagiannaki | try:
|
130 | 92359537 | Sofia Papagiannaki | user = AstakosUser.objects.get(uuid=args[0])
|
131 | 92359537 | Sofia Papagiannaki | except AstakosUser.DoesNotExist:
|
132 | 92359537 | Sofia Papagiannaki | raise CommandError("Invalid user UUID") |
133 | 0a569195 | Sofia Papagiannaki | else:
|
134 | 92359537 | Sofia Papagiannaki | raise CommandError(("Invalid user identification: " |
135 | 92359537 | Sofia Papagiannaki | "you should provide a valid user ID "
|
136 | 92359537 | Sofia Papagiannaki | "or a valid user UUID"))
|
137 | 5ce3ce4f | Sofia Papagiannaki | |
138 | df48dd1b | Giorgos Verigakis | if options.get('admin'): |
139 | df48dd1b | Giorgos Verigakis | user.is_superuser = True
|
140 | df48dd1b | Giorgos Verigakis | elif options.get('noadmin'): |
141 | df48dd1b | Giorgos Verigakis | user.is_superuser = False
|
142 | 5ce3ce4f | Sofia Papagiannaki | |
143 | ebd369d0 | Sofia Papagiannaki | if options.get('active'): |
144 | 21e0fdad | Giorgos Korfiatis | activate(user) |
145 | ebd369d0 | Sofia Papagiannaki | elif options.get('inactive'): |
146 | 21e0fdad | Giorgos Korfiatis | deactivate(user) |
147 | 5ce3ce4f | Sofia Papagiannaki | |
148 | df48dd1b | Giorgos Verigakis | invitations = options.get('invitations')
|
149 | df48dd1b | Giorgos Verigakis | if invitations is not None: |
150 | df48dd1b | Giorgos Verigakis | user.invitations = int(invitations)
|
151 | 5ce3ce4f | Sofia Papagiannaki | |
152 | 4e30244e | Sofia Papagiannaki | groupname = options.get('add-group')
|
153 | 18ffbee1 | Sofia Papagiannaki | if groupname is not None: |
154 | 18ffbee1 | Sofia Papagiannaki | try:
|
155 | 9a06d96f | Olga Brani | group = Group.objects.get(name=groupname) |
156 | 9a06d96f | Olga Brani | user.groups.add(group) |
157 | 9a06d96f | Olga Brani | except Group.DoesNotExist, e:
|
158 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
159 | 5ce3ce4f | Sofia Papagiannaki | "Group named %s does not exist\n" % groupname)
|
160 | 5ce3ce4f | Sofia Papagiannaki | |
161 | 4e30244e | Sofia Papagiannaki | groupname = options.get('delete-group')
|
162 | 4e30244e | Sofia Papagiannaki | if groupname is not None: |
163 | 4e30244e | Sofia Papagiannaki | try:
|
164 | 9a06d96f | Olga Brani | group = Group.objects.get(name=groupname) |
165 | 9a06d96f | Olga Brani | user.groups.remove(group) |
166 | 9a06d96f | Olga Brani | except Group.DoesNotExist, e:
|
167 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
168 | 5ce3ce4f | Sofia Papagiannaki | "Group named %s does not exist\n" % groupname)
|
169 | 5ce3ce4f | Sofia Papagiannaki | |
170 | 30dc8c1a | Sofia Papagiannaki | pname = options.get('add-permission')
|
171 | 30dc8c1a | Sofia Papagiannaki | if pname is not None: |
172 | 30dc8c1a | Sofia Papagiannaki | try:
|
173 | 30dc8c1a | Sofia Papagiannaki | r, created = add_user_permission(user, pname) |
174 | 30dc8c1a | Sofia Papagiannaki | if created:
|
175 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
176 | 5ce3ce4f | Sofia Papagiannaki | 'Permission: %s created successfully\n' % pname)
|
177 | 30dc8c1a | Sofia Papagiannaki | if r > 0: |
178 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
179 | 5ce3ce4f | Sofia Papagiannaki | 'Permission: %s added successfully\n' % pname)
|
180 | 5ce3ce4f | Sofia Papagiannaki | elif r == 0: |
181 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
182 | 5ce3ce4f | Sofia Papagiannaki | 'User has already permission: %s\n' % pname)
|
183 | 30dc8c1a | Sofia Papagiannaki | except Exception, e: |
184 | 30dc8c1a | Sofia Papagiannaki | raise CommandError(e)
|
185 | 5ce3ce4f | Sofia Papagiannaki | |
186 | 5ce3ce4f | Sofia Papagiannaki | pname = options.get('delete-permission')
|
187 | 30dc8c1a | Sofia Papagiannaki | if pname is not None and not user.has_perm(pname): |
188 | 30dc8c1a | Sofia Papagiannaki | try:
|
189 | 30dc8c1a | Sofia Papagiannaki | r = remove_user_permission(user, pname) |
190 | 30dc8c1a | Sofia Papagiannaki | if r < 0: |
191 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
192 | 5ce3ce4f | Sofia Papagiannaki | 'Invalid permission codename: %s\n' % pname)
|
193 | 30dc8c1a | Sofia Papagiannaki | elif r == 0: |
194 | 30dc8c1a | Sofia Papagiannaki | self.stdout.write('User has not permission: %s\n' % pname) |
195 | 30dc8c1a | Sofia Papagiannaki | elif r > 0: |
196 | 5ce3ce4f | Sofia Papagiannaki | self.stdout.write(
|
197 | 5ce3ce4f | Sofia Papagiannaki | 'Permission: %s removed successfully\n' % pname)
|
198 | 30dc8c1a | Sofia Papagiannaki | except Exception, e: |
199 | 30dc8c1a | Sofia Papagiannaki | raise CommandError(e)
|
200 | 5ce3ce4f | Sofia Papagiannaki | |
201 | ebd369d0 | Sofia Papagiannaki | level = options.get('level')
|
202 | ebd369d0 | Sofia Papagiannaki | if level is not None: |
203 | ebd369d0 | Sofia Papagiannaki | user.level = int(level)
|
204 | 5ce3ce4f | Sofia Papagiannaki | |
205 | df48dd1b | Giorgos Verigakis | password = options.get('password')
|
206 | df48dd1b | Giorgos Verigakis | if password is not None: |
207 | df48dd1b | Giorgos Verigakis | user.set_password(password) |
208 | 5ce3ce4f | Sofia Papagiannaki | |
209 | cfb15117 | Sofia Papagiannaki | password = None
|
210 | cfb15117 | Sofia Papagiannaki | if options['renew_password']: |
211 | cfb15117 | Sofia Papagiannaki | password = AstakosUser.objects.make_random_password() |
212 | cfb15117 | Sofia Papagiannaki | user.set_password(password) |
213 | 5ce3ce4f | Sofia Papagiannaki | |
214 | df48dd1b | Giorgos Verigakis | if options['renew_token']: |
215 | df48dd1b | Giorgos Verigakis | user.renew_token() |
216 | 5ce3ce4f | Sofia Papagiannaki | |
217 | 0a569195 | Sofia Papagiannaki | try:
|
218 | 0a569195 | Sofia Papagiannaki | user.save() |
219 | 0a569195 | Sofia Papagiannaki | except ValidationError, e:
|
220 | 27e26a41 | Sofia Papagiannaki | raise CommandError(e)
|
221 | 5ce3ce4f | Sofia Papagiannaki | |
222 | cfb15117 | Sofia Papagiannaki | if password:
|
223 | cfb15117 | Sofia Papagiannaki | self.stdout.write('User\'s new password: %s\n' % password) |
224 | 764d99c4 | Giorgos Korfiatis | |
225 | 764d99c4 | Giorgos Korfiatis | set_base_quota = options.get('set_base_quota')
|
226 | 764d99c4 | Giorgos Korfiatis | if set_base_quota is not None: |
227 | 764d99c4 | Giorgos Korfiatis | resource, capacity = set_base_quota |
228 | 764d99c4 | Giorgos Korfiatis | self.set_limit(user, resource, capacity, False) |
229 | 764d99c4 | Giorgos Korfiatis | |
230 | 764d99c4 | Giorgos Korfiatis | def set_limit(self, user, resource, capacity, force): |
231 | 764d99c4 | Giorgos Korfiatis | if capacity != 'default': |
232 | 764d99c4 | Giorgos Korfiatis | try:
|
233 | 764d99c4 | Giorgos Korfiatis | capacity = int(capacity)
|
234 | 764d99c4 | Giorgos Korfiatis | except ValueError: |
235 | 764d99c4 | Giorgos Korfiatis | m = "Please specify capacity as a decimal integer or 'default'"
|
236 | 764d99c4 | Giorgos Korfiatis | raise CommandError(m)
|
237 | 764d99c4 | Giorgos Korfiatis | |
238 | 764d99c4 | Giorgos Korfiatis | try:
|
239 | 764d99c4 | Giorgos Korfiatis | quota, default_capacity = user.get_resource_policy(resource) |
240 | 764d99c4 | Giorgos Korfiatis | except Resource.DoesNotExist:
|
241 | 764d99c4 | Giorgos Korfiatis | raise CommandError("No such resource: %s" % resource) |
242 | 764d99c4 | Giorgos Korfiatis | |
243 | 764d99c4 | Giorgos Korfiatis | current = quota.capacity if quota is not None else 'default' |
244 | 764d99c4 | Giorgos Korfiatis | |
245 | 764d99c4 | Giorgos Korfiatis | if not force: |
246 | 764d99c4 | Giorgos Korfiatis | self.stdout.write("user: %s (%s)\n" % (user.uuid, user.username)) |
247 | 764d99c4 | Giorgos Korfiatis | self.stdout.write("default capacity: %s\n" % default_capacity) |
248 | 764d99c4 | Giorgos Korfiatis | self.stdout.write("current capacity: %s\n" % current) |
249 | 764d99c4 | Giorgos Korfiatis | self.stdout.write("new capacity: %s\n" % capacity) |
250 | 764d99c4 | Giorgos Korfiatis | self.stdout.write("Confirm? (y/n) ") |
251 | 764d99c4 | Giorgos Korfiatis | response = raw_input()
|
252 | 764d99c4 | Giorgos Korfiatis | if string.lower(response) not in ['y', 'yes']: |
253 | 764d99c4 | Giorgos Korfiatis | self.stdout.write("Aborted.\n") |
254 | 764d99c4 | Giorgos Korfiatis | return
|
255 | 764d99c4 | Giorgos Korfiatis | |
256 | 764d99c4 | Giorgos Korfiatis | if capacity == 'default': |
257 | 764d99c4 | Giorgos Korfiatis | try:
|
258 | 764d99c4 | Giorgos Korfiatis | quotas.remove_base_quota(user, resource) |
259 | 764d99c4 | Giorgos Korfiatis | except Exception as e: |
260 | 764d99c4 | Giorgos Korfiatis | import traceback |
261 | 764d99c4 | Giorgos Korfiatis | traceback.print_exc() |
262 | 764d99c4 | Giorgos Korfiatis | raise CommandError("Failed to remove policy: %s" % e) |
263 | 764d99c4 | Giorgos Korfiatis | else:
|
264 | 764d99c4 | Giorgos Korfiatis | try:
|
265 | 764d99c4 | Giorgos Korfiatis | quotas.add_base_quota(user, resource, capacity) |
266 | 764d99c4 | Giorgos Korfiatis | except Exception as e: |
267 | 764d99c4 | Giorgos Korfiatis | raise CommandError("Failed to add policy: %s" % e) |