Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 1 | from core.models import User,Site,Service,SingletonModel,PlCoreBase,Slice |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 2 | import os |
| 3 | from django.db import models |
| 4 | from django.forms.models import model_to_dict |
| 5 | from bitfield import BitField |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 6 | from django.core.exceptions import ValidationError |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 7 | |
| 8 | # Create your models here. |
| 9 | |
| 10 | class SyndicateService(SingletonModel,Service): |
| 11 | class Meta: |
| 12 | app_label = "syndicate" |
| 13 | verbose_name = "Syndicate Service" |
| 14 | verbose_name_plural = "Syndicate Service" |
| 15 | |
| 16 | def __unicode__(self): return u'Syndicate Service' |
| 17 | |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 18 | |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 19 | class SyndicatePrincipal(PlCoreBase): |
| 20 | class Meta: |
| 21 | app_label = "syndicate" |
| 22 | |
| 23 | # for now, this is a user email address |
| 24 | principal_id = models.TextField() |
| 25 | public_key_pem = models.TextField() |
| 26 | sealed_private_key = models.TextField() |
| 27 | |
| 28 | def __unicode__self(self): return "%s" % self.principal_id |
| 29 | |
| 30 | |
| 31 | class Volume(PlCoreBase): |
| 32 | class Meta: |
| 33 | app_label = "syndicate" |
| 34 | |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 35 | name = models.CharField(max_length=64, help_text="Human-readable, searchable name of the Volume") |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 36 | |
| 37 | owner_id = models.ForeignKey(User, verbose_name='Owner') |
| 38 | |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 39 | description = models.TextField(null=True, blank=True,max_length=130, help_text="Human-readable description of what this Volume is used for.") |
| 40 | blocksize = models.PositiveIntegerField(help_text="Number of bytes per block.") |
| 41 | private = models.BooleanField(default=True, help_text="Indicates if the Volume is visible to users other than the Volume Owner and Syndicate Administrators.") |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 42 | archive = models.BooleanField(default=False, help_text="Indicates if this Volume is read-only, and only an Aquisition Gateway owned by the Volume owner (or Syndicate admin) can write to it.") |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 43 | |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 44 | CAP_READ_DATA = 1 |
| 45 | CAP_WRITE_DATA = 2 |
| 46 | CAP_HOST_DATA = 4 |
| 47 | |
| 48 | # NOTE: preserve order of capabilities here... |
| 49 | default_gateway_caps = BitField(flags=("read data", "write data", "host files"), verbose_name='Default User Capabilities') |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 50 | |
| 51 | def __unicode__(self): return self.name |
| 52 | |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 53 | |
| 54 | class VolumeAccessRight(PlCoreBase): |
| 55 | class Meta: |
| 56 | app_label = "syndicate" |
| 57 | |
| 58 | owner_id = models.ForeignKey(User, verbose_name='user') |
| 59 | |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 60 | volume = models.ForeignKey(Volume) |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 61 | gateway_caps = BitField(flags=("read data", "write data", "host files"), verbose_name="User Capabilities") |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 62 | |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 63 | def __unicode__(self): return "%s-%s" % (self.owner_id.email, self.volume.name) |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 64 | |
Siobhan Tully | cf04fb6 | 2014-01-11 11:25:57 -0500 | [diff] [blame] | 65 | |
Scott Baker | 65a670a | 2014-05-08 22:14:13 -0700 | [diff] [blame] | 66 | class VolumeSlice(PlCoreBase): |
| 67 | class Meta: |
| 68 | app_label = "syndicate" |
| 69 | |
| 70 | volume_id = models.ForeignKey(Volume, verbose_name="Volume") |
| 71 | slice_id = models.ForeignKey(Slice, verbose_name="Slice") |
| 72 | gateway_caps = BitField(flags=("read data", "write data", "host files"), verbose_name="Slice Capabilities") |
| 73 | |
| 74 | peer_portnum = models.PositiveIntegerField(help_text="User Gateway port", verbose_name="Client peer-to-peer cache port") |
| 75 | replicate_portnum = models.PositiveIntegerField(help_text="Replica Gateway port", verbose_name="Replication service port") |
| 76 | |
| 77 | credentials_blob = models.TextField(null=True, blank=True, help_text="Encrypted slice credentials") |
| 78 | |
| 79 | def __unicode__(self): return "%s-%s" % (self.volume_id.name, self.slice_id.name) |
| 80 | |
| 81 | def clean(self): |
| 82 | """ |
| 83 | Verify that our fields are in order: |
| 84 | * peer_portnum and replicate_portnum have to be valid port numbers between 1025 and 65534 |
| 85 | * peer_portnum and replicate_portnum cannot be changed once set. |
| 86 | """ |
| 87 | |
| 88 | if self.peer_portnum < 1025 or self.peer_portnum > 65534: |
| 89 | raise ValidationError( "Client peer-to-peer cache port number must be between 1025 and 65534" ) |
| 90 | |
| 91 | if self.replicate_portnum < 1025 or self.replicate_portnum > 65534: |
| 92 | raise ValidationError( "Replication service port number must be between 1025 and 65534" ) |
| 93 | |