~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to ivle/database.py

  • Committer: William Grant
  • Date: 2009-01-20 06:00:55 UTC
  • mto: This revision was merged to the branch mainline in revision 1090.
  • Revision ID: grantw@unimelb.edu.au-20090120060055-iuvd8hycor67acfa
ivle.rpc.decorators: Add (new package, too). Has a couple of decorators to
    apply most security policy in userservice, making it significantly shorter
    and easier to audit.
www/apps/userservice: Use the decorators to protect all actions whose existing
    policy can be easily replaced with them.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
            'ProjectSet', 'Project', 'ProjectGroup', 'ProjectGroupMembership',
40
40
            'Exercise', 'Worksheet', 'WorksheetExercise',
41
41
            'ExerciseSave', 'ExerciseAttempt',
42
 
            'AlreadyEnrolledError', 'TestCase', 'TestSuite', 'TestSuiteVar'
 
42
            'AlreadyEnrolledError'
43
43
        ]
44
44
 
45
45
def _kwarg_init(self, **kwargs):
53
53
    """
54
54
    Returns the Storm connection string, generated from the conf file.
55
55
    """
56
 
 
57
 
    clusterstr = ''
58
 
    if ivle.conf.db_user:
59
 
        clusterstr += ivle.conf.db_user
60
 
        if ivle.conf.db_password:
61
 
            clusterstr += ':' + ivle.conf.db_password
62
 
        clusterstr += '@'
63
 
 
64
 
    host = ivle.conf.db_host or 'localhost'
65
 
    port = ivle.conf.db_port or 5432
66
 
 
67
 
    clusterstr += '%s:%d' % (host, port)
68
 
 
69
 
    return "postgres://%s/%s" % (clusterstr, ivle.conf.db_dbname)
 
56
    return "postgres://%s:%s@%s:%d/%s" % (ivle.conf.db_user,
 
57
        ivle.conf.db_password, ivle.conf.db_host, ivle.conf.db_port,
 
58
        ivle.conf.db_dbname)
70
59
 
71
60
def get_store():
72
61
    """
141
130
        fieldval = self.acct_exp
142
131
        return fieldval is not None and datetime.datetime.now() > fieldval
143
132
 
144
 
    @property
145
 
    def valid(self):
146
 
        return self.state == 'enabled' and not self.account_expired
147
 
 
148
133
    def _get_enrolments(self, justactive):
149
134
        return Store.of(self).find(Enrolment,
150
135
            Enrolment.user_id == self.id,
211
196
        """
212
197
        return store.find(cls, cls.login == unicode(login)).one()
213
198
 
214
 
    def get_permissions(self, user):
215
 
        if user and user.rolenm == 'admin' or user is self:
216
 
            return set(['view', 'edit'])
217
 
        else:
218
 
            return set()
219
 
 
220
199
# SUBJECTS AND ENROLMENTS #
221
200
 
222
201
class Subject(Storm):
235
214
    def __repr__(self):
236
215
        return "<%s '%s'>" % (type(self).__name__, self.short_name)
237
216
 
238
 
    def get_permissions(self, user):
239
 
        perms = set()
240
 
        if user is not None:
241
 
            perms.add('view')
242
 
            if user.rolenm == 'admin':
243
 
                perms.add('edit')
244
 
        return perms
245
 
 
246
217
class Semester(Storm):
247
218
    __storm_table__ = "semester"
248
219
 
275
246
                           'User.id')
276
247
    project_sets = ReferenceSet(id, 'ProjectSet.offering_id')
277
248
 
278
 
    worksheets = ReferenceSet(id, 'Worksheet.offering_id')
279
 
 
280
249
    __init__ = _kwarg_init
281
250
 
282
251
    def __repr__(self):
295
264
        e = Enrolment(user=user, offering=self, active=True)
296
265
        self.enrolments.add(e)
297
266
 
298
 
    def get_permissions(self, user):
299
 
        perms = set()
300
 
        if user is not None:
301
 
            perms.add('view')
302
 
            if user.rolenm == 'admin':
303
 
                perms.add('edit')
304
 
        return perms
305
 
 
306
267
class Enrolment(Storm):
307
268
    __storm_table__ = "enrolment"
308
269
    __storm_primary__ = "user_id", "offering_id"
410
371
    # Note: Table "problem" is called "Exercise" in the Object layer, since
411
372
    # it's called that everywhere else.
412
373
    __storm_table__ = "problem"
413
 
#TODO: Add in a field for the user-friendly identifier
414
 
    id = Unicode(primary=True, name="identifier")
415
 
    name = Unicode()
416
 
    description = Unicode()
417
 
    partial = Unicode()
418
 
    solution = Unicode()
419
 
    include = Unicode()
420
 
    num_rows = Int()
 
374
 
 
375
    id = Int(primary=True, name="problemid")
 
376
    name = Unicode(name="identifier")
 
377
    spec = Unicode()
421
378
 
422
379
    worksheets = ReferenceSet(id,
423
380
        'WorksheetExercise.exercise_id',
424
381
        'WorksheetExercise.worksheet_id',
425
382
        'Worksheet.id'
426
383
    )
427
 
    
428
 
    test_suites = ReferenceSet(id, 'TestSuite.exercise_id')
429
384
 
430
385
    __init__ = _kwarg_init
431
386
 
432
387
    def __repr__(self):
433
388
        return "<%s %s>" % (type(self).__name__, self.name)
434
389
 
 
390
    @classmethod
 
391
    def get_by_name(cls, store, name):
 
392
        """
 
393
        Get the Exercise from the db associated with a given store and name.
 
394
        If the exercise is not in the database, creates it and inserts it
 
395
        automatically.
 
396
        """
 
397
        ex = store.find(cls, cls.name == unicode(name)).one()
 
398
        if ex is not None:
 
399
            return ex
 
400
        ex = Exercise(name=unicode(name))
 
401
        store.add(ex)
 
402
        store.commit()
 
403
        return ex
435
404
 
436
405
class Worksheet(Storm):
437
406
    __storm_table__ = "worksheet"
439
408
    id = Int(primary=True, name="worksheetid")
440
409
    # XXX subject is not linked to a Subject object. This is a property of
441
410
    # the database, and will be refactored.
442
 
    offering_id = Int(name="offeringid")
 
411
    subject = Unicode()
443
412
    name = Unicode(name="identifier")
444
413
    assessable = Bool()
445
414
    mtime = DateTime()
446
415
 
447
 
    attempts = ReferenceSet(id, "ExerciseAttempt.worksheetid")
448
 
    offering = Reference(offering_id, 'Offering.id')
449
 
 
450
416
    exercises = ReferenceSet(id,
451
417
        'WorksheetExercise.worksheet_id',
452
418
        'WorksheetExercise.exercise_id',
456
422
    # "optional" field.
457
423
    worksheet_exercises = ReferenceSet(id,
458
424
        'WorksheetExercise.worksheet_id')
459
 
        
460
425
 
461
426
    __init__ = _kwarg_init
462
427
 
483
448
        """
484
449
        store.find(WorksheetExercise,
485
450
            WorksheetExercise.worksheet == self).remove()
486
 
            
487
 
    def get_permissions(self, user):
488
 
        return self.offering.get_permissions(user)
489
451
 
490
452
class WorksheetExercise(Storm):
491
453
    __storm_table__ = "worksheet_problem"
493
455
 
494
456
    worksheet_id = Int(name="worksheetid")
495
457
    worksheet = Reference(worksheet_id, Worksheet.id)
496
 
    exercise_id = Unicode(name="problemid")
 
458
    exercise_id = Int(name="problemid")
497
459
    exercise = Reference(exercise_id, Exercise.id)
498
460
    optional = Bool()
499
461
 
515
477
    __storm_table__ = "problem_save"
516
478
    __storm_primary__ = "exercise_id", "user_id", "date"
517
479
 
518
 
    exercise_id = Unicode(name="problemid")
 
480
    exercise_id = Int(name="problemid")
519
481
    exercise = Reference(exercise_id, Exercise.id)
520
482
    user_id = Int(name="loginid")
521
483
    user = Reference(user_id, User.id)
522
484
    date = DateTime()
523
485
    text = Unicode()
524
 
    worksheetid = Int()
525
 
    worksheet = Reference(worksheetid, Worksheet.id)
526
486
 
527
487
    __init__ = _kwarg_init
528
488
 
551
511
    text = Unicode(name="attempt")
552
512
    complete = Bool()
553
513
    active = Bool()
554
 
    
555
 
    def get_permissions(self, user):
556
 
        return set(['view']) if user is self.user else set()
557
 
  
558
 
class TestSuite(Storm):
559
 
    """A Testsuite acts as a container for the test cases of an exercise."""
560
 
    __storm_table__ = "test_suite"
561
 
    __storm_primary__ = "exercise_id", "suiteid"
562
 
    
563
 
    suiteid = Int()
564
 
    exercise_id = Unicode(name="problemid")
565
 
    description = Unicode()
566
 
    seq_no = Int()
567
 
    function = Unicode()
568
 
    stdin = Unicode()
569
 
    exercise = Reference(exercise_id, Exercise.id)
570
 
    test_cases = ReferenceSet(suiteid, 'TestCase.suiteid')
571
 
    variables = ReferenceSet(suiteid, 'TestSuiteVar.suiteid')
572
 
 
573
 
class TestCase(Storm):
574
 
    """A TestCase is a member of a TestSuite.
575
 
    
576
 
    It contains the data necessary to check if an exercise is correct"""
577
 
    __storm_table__ = "test_case"
578
 
    __storm_primary__ = "testid", "suiteid"
579
 
    
580
 
    testid = Int()
581
 
    suiteid = Int()
582
 
    suite = Reference(suiteid, "TestSuite.suiteid")
583
 
    passmsg = Unicode()
584
 
    failmsg = Unicode()
585
 
    test_default = Unicode()
586
 
    seq_no = Int()
587
 
    
588
 
    parts = ReferenceSet(testid, "TestCasePart.testid")
589
 
    
590
 
    __init__ = _kwarg_init
591
 
 
592
 
class TestSuiteVar(Storm):
593
 
    """A container for the arguments of a Test Suite"""
594
 
    __storm_table__ = "suite_variables"
595
 
    __storm_primary__ = "varid"
596
 
    
597
 
    varid = Int()
598
 
    suiteid = Int()
599
 
    var_name = Unicode()
600
 
    var_value = Unicode()
601
 
    var_type = Unicode()
602
 
    arg_no = Int()
603
 
    
604
 
    suite = Reference(suiteid, "TestSuite.suiteid")
605
 
    
606
 
    __init__ = _kwarg_init
607
 
    
608
 
class TestCasePart(Storm):
609
 
    """A container for the test elements of a Test Case"""
610
 
    __storm_table__ = "test_case_parts"
611
 
    __storm_primary__ = "partid"
612
 
    
613
 
    partid = Int()
614
 
    testid = Int()
615
 
    
616
 
    part_type = Unicode()
617
 
    test_type = Unicode()
618
 
    data = Unicode()
619
 
    filename = Unicode()
620
 
    
621
 
    test = Reference(testid, "TestCase.testid")
622
 
    
623
 
    __init__ = _kwarg_init