diff mbox

[Branch,~linaro-validation/lava-scheduler/trunk] Rev 142: make testjob a restricted resource, and update views to reflect restrictions

Message ID 20120307021311.25596.58212.launchpad@ackee.canonical.com
State Accepted
Headers show

Commit Message

Michael-Doyle Hudson March 7, 2012, 2:13 a.m. UTC
Merge authors:
  Michael Hudson-Doyle (mwhudson)
Related merge proposals:
  https://code.launchpad.net/~mwhudson/lava-scheduler/restricted-resource-job/+merge/94497
  proposed by: Michael Hudson-Doyle (mwhudson)
  review: Approve - Zygmunt Krynicki (zkrynicki)
------------------------------------------------------------
revno: 142 [merge]
committer: Michael Hudson-Doyle <michael.hudson@linaro.org>
branch nick: trunk
timestamp: Wed 2012-03-07 15:11:53 +1300
message:
  make testjob a restricted resource, and update views to reflect restrictions
added:
  lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py
  lava_scheduler_app/migrations/0019_set_testjob_owner.py
modified:
  lava_scheduler_app/models.py
  lava_scheduler_app/tests.py
  lava_scheduler_app/views.py
  lava_scheduler_daemon/dbjobsource.py
  setup.py


--
lp:lava-scheduler
https://code.launchpad.net/~linaro-validation/lava-scheduler/trunk

You are subscribed to branch lp:lava-scheduler.
To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-scheduler/trunk/+edit-subscription
diff mbox

Patch

=== added file 'lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py'
--- lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py	1970-01-01 00:00:00 +0000
+++ lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py	2012-02-28 03:53:06 +0000
@@ -0,0 +1,134 @@ 
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        
+        # Adding field 'TestJob.user'
+        db.add_column('lava_scheduler_app_testjob', 'user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True), keep_default=False)
+
+        # Adding field 'TestJob.group'
+        db.add_column('lava_scheduler_app_testjob', 'group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Group'], null=True, blank=True), keep_default=False)
+
+        # Adding field 'TestJob.is_public'
+        db.add_column('lava_scheduler_app_testjob', 'is_public', self.gf('django.db.models.fields.BooleanField')(default=True), keep_default=False)
+
+
+    def backwards(self, orm):
+        
+        # Deleting field 'TestJob.user'
+        db.delete_column('lava_scheduler_app_testjob', 'user_id')
+
+        # Deleting field 'TestJob.group'
+        db.delete_column('lava_scheduler_app_testjob', 'group_id')
+
+        # Deleting field 'TestJob.is_public'
+        db.delete_column('lava_scheduler_app_testjob', 'is_public')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'lava_scheduler_app.device': {
+            'Meta': {'object_name': 'Device'},
+            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
+            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
+            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
+            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
+            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'lava_scheduler_app.devicestatetransition': {
+            'Meta': {'object_name': 'DeviceStateTransition'},
+            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
+            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'new_state': ('django.db.models.fields.IntegerField', [], {}),
+            'old_state': ('django.db.models.fields.IntegerField', [], {})
+        },
+        'lava_scheduler_app.devicetype': {
+            'Meta': {'object_name': 'DeviceType'},
+            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
+        },
+        'lava_scheduler_app.tag': {
+            'Meta': {'object_name': 'Tag'},
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
+        },
+        'lava_scheduler_app.testjob': {
+            'Meta': {'object_name': 'TestJob'},
+            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
+            'definition': ('django.db.models.fields.TextField', [], {}),
+            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
+            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
+            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
+            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
+            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
+            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
+        },
+        'linaro_django_xmlrpc.authtoken': {
+            'Meta': {'object_name': 'AuthToken'},
+            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'secret': ('django.db.models.fields.CharField', [], {'default': "'g13kpfwrkljb08chbabb0zyr642p4ukfqoc18qxmjc1zefpb0cfeddzotwot4cs1ltzh83wl5g0e7177da4n0nn5zmax8hyo8se7cbqf784y8qe6m03g0ch90uwfbpry'", 'unique': 'True', 'max_length': '128'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['lava_scheduler_app']

=== added file 'lava_scheduler_app/migrations/0019_set_testjob_owner.py'
--- lava_scheduler_app/migrations/0019_set_testjob_owner.py	1970-01-01 00:00:00 +0000
+++ lava_scheduler_app/migrations/0019_set_testjob_owner.py	2012-03-07 01:56:57 +0000
@@ -0,0 +1,123 @@ 
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+    def forwards(self, orm):
+        "Write your forwards methods here."
+        orm['lava_scheduler_app.TestJob'].objects.update(
+            user=models.F('submitter'))
+
+
+    def backwards(self, orm):
+        "Write your backwards methods here."
+        orm['lava_scheduler_app.TestJob'].objects.update(
+            user=None)
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'lava_scheduler_app.device': {
+            'Meta': {'object_name': 'Device'},
+            'current_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
+            'device_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.DeviceType']"}),
+            'health_status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '200', 'primary_key': 'True'}),
+            'last_health_report_job': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'unique': 'True', 'null': 'True', 'to': "orm['lava_scheduler_app.TestJob']"}),
+            'status': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'lava_scheduler_app.devicestatetransition': {
+            'Meta': {'object_name': 'DeviceStateTransition'},
+            'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'device': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'transitions'", 'to': "orm['lava_scheduler_app.Device']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'job': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['lava_scheduler_app.TestJob']", 'null': 'True', 'blank': 'True'}),
+            'message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'new_state': ('django.db.models.fields.IntegerField', [], {}),
+            'old_state': ('django.db.models.fields.IntegerField', [], {})
+        },
+        'lava_scheduler_app.devicetype': {
+            'Meta': {'object_name': 'DeviceType'},
+            'health_check_job': ('django.db.models.fields.TextField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'primary_key': 'True', 'db_index': 'True'})
+        },
+        'lava_scheduler_app.tag': {
+            'Meta': {'object_name': 'Tag'},
+            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'})
+        },
+        'lava_scheduler_app.testjob': {
+            'Meta': {'object_name': 'TestJob'},
+            'actual_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
+            'definition': ('django.db.models.fields.TextField', [], {}),
+            'description': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'end_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+            'health_check': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'log_file': ('django.db.models.fields.files.FileField', [], {'default': 'None', 'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'requested_device': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.Device']"}),
+            'requested_device_type': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'+'", 'null': 'True', 'blank': 'True', 'to': "orm['lava_scheduler_app.DeviceType']"}),
+            'results_link': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '400', 'null': 'True', 'blank': 'True'}),
+            'start_time': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'submit_time': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'submit_token': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['linaro_django_xmlrpc.AuthToken']", 'null': 'True', 'blank': 'True'}),
+            'submitter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['auth.User']"}),
+            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['lava_scheduler_app.Tag']", 'symmetrical': 'False', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
+        },
+        'linaro_django_xmlrpc.authtoken': {
+            'Meta': {'object_name': 'AuthToken'},
+            'created_on': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'last_used_on': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+            'secret': ('django.db.models.fields.CharField', [], {'default': "'ymu1iwklrasagpior1qddpatt0qzmf6lcy5bhctm7q4csn4gnjq5wizxljd60j4acjpjhkfiu3bc6ze6f3xakitusy0ujjiu6j2sxz0itgwf2g4h6lcmu07h98mqdtne'", 'unique': 'True', 'max_length': '128'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_tokens'", 'to': "orm['auth.User']"})
+        }
+    }
+
+    complete_apps = ['lava_scheduler_app']

=== modified file 'lava_scheduler_app/models.py'
--- lava_scheduler_app/models.py	2012-02-23 04:19:36 +0000
+++ lava_scheduler_app/models.py	2012-03-07 01:56:57 +0000
@@ -3,8 +3,14 @@ 
 from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
 from django.db import models
+from django.db.models.query import QuerySet
 from django.utils.translation import ugettext as _
 
+
+from django_restricted_resource.managers import RestrictedResourceManager
+from django_restricted_resource.models import RestrictedResource
+from django_restricted_resource.utils import filter_bogus_users
+
 from linaro_django_xmlrpc.models import AuthToken
 
 class JSONDataError(ValueError):
@@ -117,6 +123,8 @@ 
             "requested_device",
             "requested_device_type",
             "submitter",
+            "user",
+            "group",
         ).filter(
             actual_device=self
         ).order_by(
@@ -153,7 +161,8 @@ 
     #    return device_type.device_set.all()
 
 
-class TestJob(models.Model):
+
+class TestJob(RestrictedResource):
     """
     A test job is a test process that will be run on a Device.
     """
@@ -179,6 +188,7 @@ 
     submitter = models.ForeignKey(
         User,
         verbose_name = _(u"Submitter"),
+        related_name = '+',
     )
 
     submit_token = models.ForeignKey(AuthToken, null=True, blank=True)
@@ -278,7 +288,7 @@ 
         job = TestJob(
             definition=json_data, submitter=user, requested_device=target,
             requested_device_type=device_type, description=job_name,
-            health_check=is_check)
+            health_check=is_check, user=user)
         job.save()
         for tag in tags:
             job.tags.add(tag)

=== modified file 'lava_scheduler_app/tests.py'
--- lava_scheduler_app/tests.py	2012-02-23 04:12:07 +0000
+++ lava_scheduler_app/tests.py	2012-02-28 03:53:16 +0000
@@ -89,6 +89,8 @@ 
             definition = json.dumps({})
         if submitter is None:
             submitter = self.make_user()
+        if 'user' not in kwargs:
+            kwargs['user'] = submitter
         testjob = TestJob(
             definition=definition, submitter=submitter, **kwargs)
         testjob.save()

=== modified file 'lava_scheduler_app/views.py'
--- lava_scheduler_app/views.py	2012-03-06 04:20:03 +0000
+++ lava_scheduler_app/views.py	2012-03-07 01:59:51 +0000
@@ -80,10 +80,19 @@ 
         return pklink(record)
 
 
+class RestrictedIDLinkColumn(IDLinkColumn):
+
+    def render(self, record, table):
+        if record.is_accessible_by(table.context.get('request').user):
+            return pklink(record)
+        else:
+            return record.pk
+
+
 def all_jobs_with_device_sort():
     return TestJob.objects.select_related(
         "actual_device", "requested_device", "requested_device_type",
-        "submitter").extra(
+        "submitter", "user", "group").extra(
         select={
             'device_sort': 'coalesce(actual_device_id, requested_device_id, requested_device_type_id)'
             }).all()
@@ -106,7 +115,7 @@ 
         else:
             return ''
 
-    id = IDLinkColumn()
+    id = RestrictedIDLinkColumn()
     status = Column()
     device = Column(accessor='device_sort')
     description = Column(attrs=Attrs(width="30%"))
@@ -163,6 +172,11 @@ 
         RequestContext(request))
 
 
+def get_restricted_job(user, pk):
+    return get_object_or_404(
+        TestJob.objects.accessible_by_principal(user), pk=pk)
+
+
 class DeviceHealthTable(AjaxTable):
 
     def get_queryset(self):
@@ -276,7 +290,7 @@ 
 
 @BreadCrumb("Job #{pk}", parent=index, needs=['pk'])
 def job_detail(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
 
     data = {
         'job': job,
@@ -313,7 +327,7 @@ 
 
 
 def job_definition(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     return render_to_response(
         "lava_scheduler_app/job_definition.html",
         {
@@ -324,7 +338,7 @@ 
 
 
 def job_definition_plain(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     response = HttpResponse(job.definition, mimetype='text/plain')
     response['Content-Disposition'] = "attachment; filename=job_%d.json"%job.id
     return response
@@ -332,7 +346,7 @@ 
 
 @BreadCrumb("Complete log", parent=job_detail, needs=['pk'])
 def job_log_file(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     content = formatLogFile(job.log_file)
     return render_to_response(
         "lava_scheduler_app/job_log_file.html",
@@ -346,7 +360,7 @@ 
 
 
 def job_log_file_plain(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     response = HttpResponse(job.log_file, mimetype='text/plain')
     response['Content-Disposition'] = "attachment; filename=job_%d.log"%job.id
     return response
@@ -354,7 +368,7 @@ 
 
 def job_log_incremental(request, pk):
     start = int(request.GET.get('start', 0))
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     log_file = job.log_file
     log_file.seek(start)
     new_content = log_file.read()
@@ -369,7 +383,7 @@ 
 
 def job_full_log_incremental(request, pk):
     start = int(request.GET.get('start', 0))
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     log_file = job.log_file
     log_file.seek(start)
     new_content = log_file.read()
@@ -396,7 +410,7 @@ 
     except ValueError:
         return HttpResponseBadRequest("invalid start")
     count_present = 'count' in request.GET
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     log_file = job.log_file
     log_file.seek(0, os.SEEK_END)
     size = int(request.GET.get('count', log_file.tell()))
@@ -425,7 +439,7 @@ 
 
 @post_only
 def job_cancel(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     if job.can_cancel(request.user):
         job.cancel()
         return redirect(job)
@@ -435,7 +449,7 @@ 
 
 
 def job_json(request, pk):
-    job = get_object_or_404(TestJob, pk=pk)
+    job = get_restricted_job(request.user, pk)
     json_text = simplejson.dumps({
         'status': job.get_status_display(),
         'results_link': job.results_link,

=== modified file 'lava_scheduler_daemon/dbjobsource.py'
--- lava_scheduler_daemon/dbjobsource.py	2012-03-05 03:12:25 +0000
+++ lava_scheduler_daemon/dbjobsource.py	2012-03-07 01:59:51 +0000
@@ -126,7 +126,7 @@ 
             job_name = job_data.get('job_name')
             job = TestJob(
                 definition=job_json, submitter=user, description=job_name,
-                health_check=True)
+                health_check=True, owner=user, is_public=True)
             job.save()
             return job
 

=== modified file 'setup.py'
--- setup.py	2012-03-01 04:34:01 +0000
+++ setup.py	2012-03-05 00:23:16 +0000
@@ -33,6 +33,7 @@ 
     scheduler = lava_scheduler_app.extension:SchedulerExtension
     """,
     install_requires=[
+        "django-restricted-resource",
         "django-tables2",
         "lava-server >= 0.10",
         "simplejson",