170
"""Handler for the Console Service AJAX backend application."""
173
req.throw_error(req.HTTP_FORBIDDEN,
174
"You are not logged in to IVLE.")
175
if len(req.path) > 0 and req.path[-1] == os.sep:
179
# The path determines which "command" we are receiving
180
fields = req.get_fieldstorage()
182
func = actions_map[req.path]
184
req.throw_error(req.HTTP_BAD_REQUEST,
185
"%s is not a valid userservice action." % repr(req.path))
167
class UserServiceView(BaseView):
168
def __init__(self, req, path):
169
if len(path) > 0 and path[-1] == os.sep:
170
self.path = path[:-1]
174
def authorize(self, req):
175
# XXX: activate_me isn't called by a valid user, so is special for now.
176
if req.path == 'activate_me' and get_user_details(req) is not None:
178
return req.user is not None
180
def render(self, req):
181
# The path determines which "command" we are receiving
182
fields = req.get_fieldstorage()
184
func = actions_map[self.path]
189
class Plugin(ViewPlugin):
191
('userservice/*path', UserServiceView)
188
194
@require_method('POST')
189
195
def handle_activate_me(req, fields):
204
210
"accepting" the terms - at least this way requires them to acknowledge
205
211
their acceptance). It must only be called through a POST request.
209
declaration = fields.getfirst('declaration')
210
except AttributeError:
211
declaration = None # Will fail next test
212
if declaration != USER_DECLARATION:
213
req.throw_error(req.HTTP_BAD_REQUEST,
214
"Please use the Terms of Service form instead of talking to "
215
"this service directly.")
217
# Make sure the user's status is "no_agreement", and set status to
218
# pending, within the one transaction. This ensures we only do this
221
# Check that the user's status is "no_agreement".
222
# (Both to avoid redundant calls, and to stop disabled users from
223
# re-enabling their accounts).
224
if req.user.state != "no_agreement":
225
req.throw_error(req.HTTP_BAD_REQUEST,
226
"You have already agreed to the terms.")
227
# Write state "pending" to ensure we don't try this again
228
req.user.state = u"pending"
234
# Get the arguments for usermgt.activate_user from the session
235
# (The user must have already logged in to use this app)
237
"login": req.user.login,
239
msg = {'activate_user': args}
241
# Release our lock on the db so usrmgt can write
244
# Try and contact the usrmgt server
246
response = chat.chat(usrmgt_host, usrmgt_port, msg, usrmgt_magic)
247
except cjson.DecodeError:
248
# Gave back rubbish - set the response to failure
249
response = {'response': 'usrmgt-failure'}
251
# Get the staus of the users request
253
status = response['response']
258
req.user.state = u"enabled"
260
# Reset the user back to no agreement
261
req.user.state = u"no_agreement"
265
req.content_type = "text/plain"
266
req.write(cjson.encode(response))
214
user = get_user_details(req)
217
declaration = fields.getfirst('declaration')
218
except AttributeError:
219
declaration = None # Will fail next test
220
if declaration != USER_DECLARATION:
223
# Make sure the user's status is "no_agreement", and set status to
224
# pending, within the one transaction. This ensures we only do this
227
# Check that the user's status is "no_agreement".
228
# (Both to avoid redundant calls, and to stop disabled users from
229
# re-enabling their accounts).
230
if user.state != "no_agreement":
231
raise BadRequest("You have already agreed to the terms.")
232
# Write state "pending" to ensure we don't try this again
233
user.state = u"pending"
268
235
req.store.rollback()
239
# Get the arguments for usermgt.activate_user from the session
240
# (The user must have already logged in to use this app)
244
msg = {'activate_user': args}
246
# Release our lock on the db so usrmgt can write
249
# Try and contact the usrmgt server
251
response = chat.chat(usrmgt_host, usrmgt_port, msg, usrmgt_magic)
252
except cjson.DecodeError:
253
# Gave back rubbish - set the response to failure
254
response = {'response': 'usrmgt-failure'}
256
# Get the staus of the users request
258
status = response['response']
263
user.state = u"enabled"
265
# Reset the user back to no agreement
266
user.state = u"no_agreement"
269
req.content_type = "text/plain"
270
req.write(cjson.encode(response))
271
272
create_user_fields_required = [
272
273
'login', 'fullname', 'rolenm'
506
494
offeringid = fields.getfirst('offeringid')
507
495
if offeringid is None:
508
req.throw_error(req.HTTP_BAD_REQUEST,
509
"Required: offeringid")
496
raise BadRequest("Required: offeringid")
511
498
offeringid = int(offeringid)
513
req.throw_error(req.HTTP_BAD_REQUEST,
514
"offeringid must be a integer")
500
raise BadRequest("offeringid must be an integer")
516
502
offering = req.store.get(ivle.database.Offering, offeringid)
518
504
dict_projectsets = []
520
for p in offering.project_sets:
521
dict_projectsets.append({
522
'projectsetid': p.id,
523
'max_students_per_group': p.max_students_per_group,
524
'groups': [{'groupid': g.id,
526
'nick': g.nick} for g in p.project_groups]
529
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR, repr(e))
505
for p in offering.project_sets:
506
dict_projectsets.append({
507
'projectsetid': p.id,
508
'max_students_per_group': p.max_students_per_group,
509
'groups': [{'groupid': g.id,
511
'nick': g.nick} for g in p.project_groups]
531
514
response = cjson.encode(dict_projectsets)
532
515
req.write(response)
547
530
projectsetid = fields.getfirst('projectsetid').value
548
531
groupnm = fields.getfirst('groupnm').value
549
532
if projectsetid is None or groupnm is None:
550
req.throw_error(req.HTTP_BAD_REQUEST,
551
"Required: projectsetid, groupnm")
533
raise BadRequest("Required: projectsetid, groupnm")
552
534
groupnm = unicode(groupnm)
554
536
projectsetid = int(projectsetid)
556
req.throw_error(req.HTTP_BAD_REQUEST,
557
"projectsetid must be an int")
538
raise BadRequest("projectsetid must be an integer")
558
540
# Get optional fields
559
541
nick = fields.getfirst('nick').value
560
542
if nick is not None:
561
543
nick = unicode(nick)
563
# Begin transaction since things can go wrong
545
group = ivle.database.ProjectGroup(name=groupnm,
546
project_set_id=projectsetid,
549
epoch=datetime.datetime.now())
552
# Create the group repository
553
# Yes, this is ugly, and it would be nice to just pass in the groupid,
554
# but the object isn't visible to the extra transaction in
555
# usrmgt-server until we commit, which we only do once the repo is
557
offering = group.project_set.offering
560
"subj_short_name": offering.subject.short_name,
561
"year": offering.semester.year,
562
"semester": offering.semester.semester,
563
"groupnm": group.name,
565
msg = {'create_group_repository': args}
567
# Contact the usrmgt server
565
group = ivle.database.ProjectGroup(name=groupnm,
566
project_set_id=projectsetid,
569
epoch=datetime.datetime.now())
572
# Create the group repository
573
# Yes, this is ugly, and it would be nice to just pass in the groupid,
574
# but the object isn't visible to the extra transaction in
575
# usrmgt-server until we commit, which we only do once the repo is
577
offering = group.project_set.offering
580
"subj_short_name": offering.subject.short_name,
581
"year": offering.semester.year,
582
"semester": offering.semester.semester,
583
"groupnm": group.name,
585
msg = {'create_group_repository': args}
587
# Contact the usrmgt server
589
usrmgt = chat.chat(usrmgt_host, usrmgt_port, msg, usrmgt_magic)
590
except cjson.DecodeError, e:
591
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR,
592
"Could not understand usrmgt server response: %s"%e.message)
594
if 'response' not in usrmgt or usrmgt['response']=='failure':
595
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR,
596
"Failure creating repository: %s"%str(usrmgt))
598
# Everything went OK. Lock it in
602
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR, repr(e))
569
usrmgt = chat.chat(usrmgt_host, usrmgt_port, msg, usrmgt_magic)
570
except cjson.DecodeError, e:
571
raise Exception("Could not understand usrmgt server response:" +
574
if 'response' not in usrmgt or usrmgt['response']=='failure':
575
raise Exception("Failure creating repository: " + str(usrmgt))
604
577
req.content_type = "text/plain"
615
588
groupid = fields.getfirst('groupid')
616
589
offeringid = fields.getfirst('offeringid')
617
590
if groupid is None or offeringid is None:
618
req.throw_error(req.HTTP_BAD_REQUEST,
619
"Required: groupid, offeringid")
591
raise BadRequest("Required: groupid, offeringid")
621
593
groupid = int(groupid)
623
req.throw_error(req.HTTP_BAD_REQUEST,
624
"groupid must be an int")
595
raise BadRequest("groupid must be an integer")
625
596
group = req.store.get(ivle.database.ProjectGroup, groupid)
628
599
offeringid = int(offeringid)
630
req.throw_error(req.HTTP_BAD_REQUEST,
631
"offeringid must be an int")
601
raise BadRequest("offeringid must be an integer")
632
602
offering = req.store.get(ivle.database.Offering, offeringid)
675
644
# Add membership to database
676
645
# We can't keep a transaction open until the end here, as usrmgt-server
677
646
# needs to see the changes!
647
group.members.add(user)
650
# Rebuild the svn config file
651
# Contact the usrmgt server
652
msg = {'rebuild_svn_group_config': {}}
679
group.members.add(user)
682
# Rebuild the svn config file
683
# Contact the usrmgt server
684
msg = {'rebuild_svn_group_config': {}}
686
usrmgt = chat.chat(usrmgt_host, usrmgt_port, msg, usrmgt_magic)
687
except cjson.DecodeError, e:
688
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR,
689
"Could not understand usrmgt server response: %s"%e.message)
691
if 'response' not in usrmgt or usrmgt['response']=='failure':
692
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR,
693
"Failure creating repository: %s"%str(usrmgt))
695
req.throw_error(req.HTTP_INTERNAL_SERVER_ERROR, repr(e))
654
usrmgt = chat.chat(usrmgt_host, usrmgt_port, msg, usrmgt_magic)
655
except cjson.DecodeError, e:
656
raise Exception("Could not understand usrmgt server response: %s" +
659
if 'response' not in usrmgt or usrmgt['response']=='failure':
660
raise Exception("Failure creating repository: " + str(usrmgt))
697
662
return(cjson.encode({'response': 'okay'}))