class Role(TenantAwareModel): """A role.""" uuid = models.UUIDField(default=uuid4, editable=False, unique=True, null=False) name = models.CharField(max_length=150) display_name = models.CharField(default="", max_length=150) description = models.TextField(null=True) system = models.BooleanField(default=False) platform_default = models.BooleanField(default=False) version = models.PositiveIntegerField(default=1) created = models.DateTimeField(default=timezone.now) modified = AutoDateTimeField(default=timezone.now) @property def role(self): """Get role for self.""" return self class Meta: ordering = ["name", "modified"] constraints = [ models.UniqueConstraint(fields=["name", "tenant"], name="unique role name per tenant"), models.UniqueConstraint(fields=["display_name", "tenant"], name="unique role display name per tenant"), ] def save(self, *args, **kwargs): """Ensure that display_name is populated on save.""" if not self.display_name: self.display_name = self.name super(Role, self).save(*args, **kwargs)
class Group(models.Model): """A group.""" uuid = models.UUIDField(default=uuid4, editable=False, unique=True, null=False) name = models.CharField(max_length=150, unique=True) description = models.TextField(null=True) principals = models.ManyToManyField(Principal, related_name='group') created = models.DateTimeField(default=timezone.now) modified = AutoDateTimeField(default=timezone.now) platform_default = models.BooleanField(default=False) system = models.BooleanField(default=False) def roles(self): """Roles for a group.""" return Role.objects.filter(policies__in=self.__policy_ids()).distinct() def roles_with_access(self): """Queryset for roles with access data prefetched.""" return self.roles().prefetch_related('access') def role_count(self): """Role count for a group.""" return self.roles().count() def platform_default_set(): """Queryset for platform default group.""" return Group.objects.filter(platform_default=True) def __policy_ids(self): """Policy IDs for a group.""" return self.policies.values_list('id', flat=True) class Meta: ordering = ['name', 'modified']
class Group(TenantAwareModel): """A group.""" uuid = models.UUIDField(default=uuid4, editable=False, unique=True, null=False) name = models.CharField(max_length=150) description = models.TextField(null=True) principals = models.ManyToManyField(Principal, related_name="group") created = models.DateTimeField(default=timezone.now) modified = AutoDateTimeField(default=timezone.now) platform_default = models.BooleanField(default=False) system = models.BooleanField(default=False) def roles(self): """Roles for a group.""" return Role.objects.filter(policies__in=self.__policy_ids()).distinct() def roles_with_access(self): """Queryset for roles with access data prefetched.""" return self.roles().prefetch_related("access") def role_count(self): """Role count for a group.""" return self.roles().count() def platform_default_set(): """Queryset for platform default group.""" return Group.objects.filter(platform_default=True) def __policy_ids(self): """Policy IDs for a group.""" return self.policies.values_list("id", flat=True) class Meta: ordering = ["name", "modified"] constraints = [models.UniqueConstraint(fields=["name", "tenant"], name="unique group name per tenant")]
class CrossAccountRequest(models.Model): """Cross account access request.""" request_id = models.UUIDField(default=uuid4, editable=False, unique=True, null=False, primary_key=True) target_account = models.CharField(max_length=15, default=None) user_id = models.CharField(max_length=15, default=None) created = models.DateTimeField(default=timezone.now) start_date = models.DateTimeField(default=timezone.now) end_date = models.DateTimeField(null=False, blank=False, default=None) modified = AutoDateTimeField(default=timezone.now) status = models.CharField(max_length=10, default="pending") roles = models.ManyToManyField("management.Role", through="RequestsRoles") def validate_date(self, date): """Validate that end dates are not in the past.""" if isinstance( date, datetime.datetime) and date.date() < timezone.now().date(): raise ValidationError( "Please verify the end dates are not in the past.") def validate_input_value(self): """Validate status is valid, and date is valid.""" if self.status not in STATUS_LIST: raise ValidationError( f'Unknown status "{self.status}" specified, {STATUS_LIST} are valid inputs.' ) if self.status != "expired": self.validate_date(self.end_date) if isinstance(self.end_date, datetime.datetime) and isinstance( self.start_date, datetime.datetime): if self.start_date.date() > (datetime.datetime.now() + datetime.timedelta(60)).date(): raise ValidationError( "Start date must be within 60 days of today.") if self.start_date > self.end_date: raise ValidationError( "Start date must be earlier than end date.") if self.end_date - self.start_date > datetime.timedelta(365): raise ValidationError( "Access duration may not be longer than one year.") def save(self, *args, **kwargs): """Override save method to validate some input.""" self.validate_input_value() super(CrossAccountRequest, self).save(*args, **kwargs)
class Policy(models.Model): """A policy.""" uuid = models.UUIDField(default=uuid4, editable=False, unique=True, null=False) name = models.CharField(max_length=150, unique=True) description = models.TextField(null=True) group = models.ForeignKey(Group, null=True, on_delete=models.CASCADE, related_name='policies') roles = models.ManyToManyField(Role, related_name='policies') system = models.BooleanField(default=False) created = models.DateTimeField(default=timezone.now) modified = AutoDateTimeField(default=timezone.now) class Meta: ordering = ['name', 'modified']
class Role(models.Model): """A role.""" uuid = models.UUIDField(default=uuid4, editable=False, unique=True, null=False) name = models.CharField(max_length=150, unique=True) description = models.TextField(null=True) system = models.BooleanField(default=False) platform_default = models.BooleanField(default=False) version = models.PositiveIntegerField(default=1) created = models.DateTimeField(default=timezone.now) modified = AutoDateTimeField(default=timezone.now) class Meta: ordering = ['name', 'modified']
class CrossAccountRequest(models.Model): """Cross account access request.""" request_id = models.UUIDField(default=uuid4, editable=False, unique=True, null=False, primary_key=True) target_account = models.CharField(max_length=15, default=None) user_id = models.CharField(max_length=15, default=None) created = models.DateTimeField(default=timezone.now) start_date = models.DateTimeField(default=timezone.now) end_date = models.DateTimeField(null=False, blank=False, default=None) modified = AutoDateTimeField(default=timezone.now) status = models.CharField(max_length=10, default="pending") def validate_input_value(self): """Validate status is valid, and date is valid.""" if self.status not in STATUS_LIST: raise ValidationError( f'Unknown status "{self.status}" specified, {STATUS_LIST} are valid inputs.' ) if isinstance(self.end_date, datetime.datetime) and self.end_date <= timezone.now(): raise ValidationError( "Please verify the end date, it should not be a past value.") if (isinstance(self.end_date, datetime.datetime) and isinstance(self.start_date, datetime.datetime) and self.start_date >= self.end_date): raise ValidationError("Start date must be earlier than end date.") def save(self, *args, **kwargs): """Override save method to validate some input.""" self.validate_input_value() super(CrossAccountRequest, self).save(*args, **kwargs)
class Policy(TenantAwareModel): """A policy.""" uuid = models.UUIDField(default=uuid4, editable=False, unique=True, null=False) name = models.CharField(max_length=150) description = models.TextField(null=True) group = models.ForeignKey(Group, null=True, on_delete=models.CASCADE, related_name="policies") roles = models.ManyToManyField(Role, related_name="policies") system = models.BooleanField(default=False) created = models.DateTimeField(default=timezone.now) modified = AutoDateTimeField(default=timezone.now) class Meta: ordering = ["name", "modified"] constraints = [ models.UniqueConstraint(fields=["name", "tenant"], name="unique policy name per tenant") ]