class ConsulAlerts(Model): consulalert_type = models.CharField( verbose_name=_('Service Name'), max_length=20, choices=choices.CONSULALERTS_TYPES, default='AWS-SNS', ) attributes = DictField( editable=False, verbose_name=_("Attributes"), ) enabled = models.BooleanField( verbose_name=_("Enabled"), default=True, ) class Meta: verbose_name = _("Alert Service") verbose_name_plural = _("Alert Services") ordering = ["consulalert_type"] class FreeAdmin: icon_model = "ConsulAlertsIcon" icon_object = "ConsulAlertsIcon" icon_add = "AddConsulAlertsIcon" icon_view = "ViewConsulAlertsIcon" exclude_fields = ( 'attributes', 'id', ) def __str__(self): return self.consulalert_type
class AlertService(Model): name = models.CharField( max_length=120, verbose_name=_("Name"), help_text=_("Name to identify this alert service"), ) type = models.CharField( verbose_name=_("Type"), max_length=20, default='Mail', ) attributes = DictField( blank=True, editable=False, verbose_name=_("Attributes"), ) enabled = models.BooleanField( verbose_name=_("Enabled"), default=True, ) settings = DictField( blank=True, verbose_name=_("Settings"), ) class Meta: verbose_name = _("Alert Service") verbose_name_plural = _("Alert Services") ordering = ["type"] class FreeAdmin: icon_model = "AlertServiceIcon" icon_object = "AlertServiceIcon" icon_add = "AddAlertServiceIcon" icon_view = "ViewAlertServiceIcon" exclude_fields = ( 'attributes', 'settings', 'id', ) def __str__(self): return self.name
class Alert(Model): node = models.CharField(default='A', max_length=100) source = models.TextField() key = models.TextField() datetime = models.DateTimeField() level = models.IntegerField() title = models.TextField() args = DictField() dismissed = models.BooleanField() class Meta: unique_together = (('node', 'source', 'key'), )
class AlertClasses(Model): classes = DictField(blank=True, ) class Meta: verbose_name = _("Alerts") class FreeAdmin: deletable = False icon_model = "AlertServiceIcon" icon_object = "AlertServiceIcon" icon_view = "AlertServiceIcon" icon_add = "AlertServiceIcon"
class Alert(Model): uuid = models.TextField() node = models.CharField(default='A', max_length=100) source = models.TextField() klass = models.TextField() args = DictField() key = models.TextField() datetime = models.DateTimeField() dismissed = models.BooleanField() text = models.TextField() class Meta: unique_together = (('node', 'klass', 'key'), )
class Device(Model): vm = models.ForeignKey( VM, verbose_name=_('VM'), ) dtype = models.CharField( verbose_name=_('Type'), max_length=50, choices=choices.VM_DEVTYPES, ) attributes = DictField(editable=False, ) def __unicode__(self): return '{0}:{1}'.format(self.vm, self.get_dtype_display())
class CloudCredentials(Model): name = models.CharField( verbose_name=_('Account Name'), max_length=100, ) provider = models.CharField( verbose_name=_('Provider'), max_length=50, choices=choices.CLOUD_PROVIDERS, ) attributes = DictField(editable=False, ) def __str__(self): return self.name class Meta: verbose_name = _("Cloud Credential")
class CloudSync(Model): description = models.CharField( max_length=150, verbose_name=_('Description'), ) path = PathField( verbose_name=_("Path"), abspath=False, ) credential = models.ForeignKey( 'system.CloudCredentials', verbose_name=_('Credential'), ) attributes = DictField(editable=False, ) minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_("Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), ) hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), ) daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), ) month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), ) dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), ) enabled = models.BooleanField( default=True, verbose_name=_("Enabled"), help_text=_( 'Disabling will not stop any syncs which are in progress.'), ) class Meta: verbose_name = _(u"Cloud Sync") verbose_name_plural = _(u"Cloud Syncs") ordering = ["description"] def __unicode__(self): return self.description def get_human_minute(self): if self.minute == '*': return _(u'Every minute') elif self.minute.startswith('*/'): return _(u'Every {0} minute(s)').format(self.minute.split('*/')[1]) else: return self.minute def get_human_hour(self): if self.hour == '*': return _(u'Every hour') elif self.hour.startswith('*/'): return _(u'Every {0} hour(s)').format(self.hour.split('*/')[1]) else: return self.hour def get_human_daymonth(self): if self.daymonth == '*': return _(u'Everyday') elif self.daymonth.startswith('*/'): return _(u'Every {0} days').format(self.daymonth.split('*/')[1]) else: return self.daymonth def get_human_month(self): months = self.month.split(',') if len(months) == 12 or self.month == '*': return _("Every month") mchoices = dict(choices.MONTHS_CHOICES) labels = [] for m in months: labels.append(unicode(mchoices[m])) return ', '.join(labels) def get_human_dayweek(self): weeks = self.dayweek.split(',') if len(weeks) == 7 or self.dayweek == '*': return _('Everyday') if weeks == map(str, xrange(1, 6)): return _('Weekdays') if weeks == map(str, xrange(6, 8)): return _('Weekends') wchoices = dict(choices.WEEKDAYS_CHOICES) labels = [] for w in weeks: labels.append(unicode(wchoices[str(w)])) return ', '.join(labels) def run(self): with client as c: jid = c.call('backup.sync', self.id) return jid
class bsdUsers(Model): USERNAME_FIELD = 'bsdusr_username' REQUIRED_FIELDS = [] bsdusr_uid = models.IntegerField( verbose_name=_("User ID"), validators=[MinValueValidator(0), MaxValueValidator(4294967295)], ) bsdusr_username = models.CharField( max_length=16, unique=True, default=_('User &'), verbose_name=_("Username") ) bsdusr_unixhash = models.CharField( max_length=128, blank=True, default='*', verbose_name=_("Hashed UNIX password") ) bsdusr_smbhash = models.CharField( max_length=128, blank=True, default='*', verbose_name=_("Hashed SMB password") ) bsdusr_group = models.ForeignKey( bsdGroups, on_delete=models.SET(get_sentinel_group), verbose_name=_("Primary Group ID") ) bsdusr_home = PathField( default="/nonexistent", verbose_name=_("Home Directory"), includes=["/root", "/nonexistent"], ) bsdusr_shell = models.CharField( max_length=120, default='/bin/csh', verbose_name=_("Shell"), choices=choices.SHELL_CHOICES(), ) bsdusr_full_name = models.CharField( max_length=120, verbose_name=_("Full Name") ) bsdusr_builtin = models.BooleanField( default=False, editable=False, verbose_name=_("Built-in User"), ) bsdusr_email = models.EmailField( verbose_name=_("E-mail"), blank=True ) bsdusr_password_disabled = models.BooleanField( verbose_name=_("Disable password login"), default=False, help_text=_( 'This disables all forms of password login, including for sharing.' ), ) bsdusr_locked = models.BooleanField( verbose_name=_("Lock user"), default=False, ) bsdusr_sudo = models.BooleanField( verbose_name=_("Permit Sudo"), default=False, ) bsdusr_microsoft_account = models.BooleanField( verbose_name=_("Microsoft Account"), default=False ) bsdusr_attributes = DictField( default=None, editable=False, ) is_active = True is_staff = True objects = UserManager() @classmethod def has_root_password(cls): qs = cls.objects.filter(bsdusr_uid=0).exclude(bsdusr_unixhash='*') return qs.exists() @property def bsdusr_sshpubkey(self): keysfile = '%s/.ssh/authorized_keys' % self.bsdusr_home if not os.path.exists(keysfile): return '' try: with open(keysfile, 'r') as f: keys = f.read() return keys except: return '' class Meta: verbose_name = _("User") verbose_name_plural = _("Users") ordering = ['bsdusr_builtin', 'bsdusr_username'] def __str__(self): return self.bsdusr_username def get_username(self): "Return the identifying username for this User" return getattr(self, self.USERNAME_FIELD) def natural_key(self): return (self.get_username(),) @property def is_anonymous(self): """ Always returns False. This is a way of comparing User objects to anonymous users. """ return False @property def is_authenticated(self): """ Always return True. This is a way to tell if the user has been authenticated in templates. """ return True def set_password(self, password): # Django auth backend calls set_password even if user doesnt exist if not self.bsdusr_username or not self.id: time.sleep(0.1) return with client as c: pk = c.call('user.update', self.id, {'password': password}) user = bsdUsers.objects.get(pk=pk) self.bsdusr_unixhash = user.bsdusr_unixhash self.bsdusr_smbhash = user.bsdusr_smbhash def check_password(self, raw_password): # Only allow uid 0 for now if self.bsdusr_uid != 0: return False if self.bsdusr_unixhash: if self.bsdusr_unixhash == 'x' or self.bsdusr_unixhash == '*': return False if isinstance(raw_password, bytes): raw_password = raw_password.decode('utf-8') return crypt.crypt( raw_password, str(self.bsdusr_unixhash) ) == str(self.bsdusr_unixhash) def save(self, *args, **kwargs): # TODO: Add last_login field if ( 'update_fields' in kwargs and 'last_login' in kwargs['update_fields'] ): kwargs['update_fields'].remove('last_login') super(bsdUsers, self).save(*args, **kwargs)
class CloudSync(Model): description = models.CharField( max_length=150, verbose_name=_('Description'), ) direction = models.CharField( max_length=10, verbose_name=_("Direction"), help_text=_( "Push - From local to remote. Pull - From " "remote to local." ), default='PUSH', choices=( ('PUSH', _('Push')), ('PULL', _('Pull')), ) ) path = PathField( verbose_name=_("Path"), abspath=False, ) credential = models.ForeignKey( 'system.CloudCredentials', verbose_name=_('Credential'), ) transfer_mode = models.CharField( verbose_name=_('Transfer Mode'), default='sync', choices=( ('SYNC', _('Sync')), ('COPY', _('Copy')), ('MOVE', _('Move')), ), max_length=20, ) attributes = DictField( editable=False, ) snapshot = models.BooleanField( verbose_name=_("Take snapshot"), help_text=_( "Take dataset snapshot before pushing data.", ), ) pre_script = models.TextField( blank=True, verbose_name=_("Pre-script"), help_text=_( "Script to execute before running sync.", ), ) post_script = models.TextField( blank=True, verbose_name=_("Post-script"), help_text=_( "Script to execute after running sync.", ), ) encryption = models.BooleanField( verbose_name=_("Remote encryption"), help_text=_( "This option will push encrypted files and decrypt pulled files.", ), ) filename_encryption = models.BooleanField( default=True, verbose_name=_("Filename encryption"), help_text=_( "Also encrypt filenames.", ), ) encryption_password = models.CharField( blank=True, max_length=256, verbose_name=_("Encryption password"), ) encryption_salt = models.CharField( blank=True, max_length=256, verbose_name=_("Encryption salt"), ) args = models.TextField( blank=True, max_length=255, verbose_name=_("Auxiliary arguments"), help_text=_( "These arguments will be passed to rclone." "<br>See <a href=\"https://rclone.org/docs/\">https://rclone.org/docs/</a> for help"), ) minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_( "Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), ) hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), ) daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), ) month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), ) dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), ) follow_symlinks = models.BooleanField( verbose_name=_("Follow symlinks"), help_text=_( "Follow symlinks and copy the pointed to item.", ), ) transfers = models.IntegerField( null=True, ) bwlimit = ListField( editable=False, ) exclude = ListField( editable=False, ) enabled = models.BooleanField( default=True, verbose_name=_("Enabled"), help_text=_( 'Disabling will not stop any syncs which are in progress.' ), ) class Meta: verbose_name = _("Cloud Sync") verbose_name_plural = _("Cloud Syncs") ordering = ["description"] def __str__(self): return self.description def run(self): with client as c: jid = c.call('cloudsync.sync', self.id) return jid
class CloudSync(Model): description = models.CharField( max_length=150, verbose_name=_('Description'), ) direction = models.CharField( max_length=10, verbose_name=_("Direction"), help_text=_("Push - From local to remote. Pull - From " "remote to local."), default='PUSH', choices=( ('PUSH', _('Push')), ('PULL', _('Pull')), )) path = PathField( verbose_name=_("Path"), abspath=False, ) credential = models.ForeignKey( 'system.CloudCredentials', verbose_name=_('Credential'), ) transfer_mode = models.CharField( verbose_name=_('Transfer Mode'), default='sync', choices=( ('SYNC', _('Sync')), ('COPY', _('Copy')), ('MOVE', _('Move')), ), max_length=20, ) attributes = DictField(editable=False, ) encryption = models.BooleanField( verbose_name=_("Remote encryption"), help_text=_( "This option will push encrypted files and decrypt pulled files.", ), ) filename_encryption = models.BooleanField( default=True, verbose_name=_("Filename encryption"), help_text=_("Also encrypt filenames.", ), ) encryption_password = models.CharField( blank=True, max_length=256, verbose_name=_("Encryption password"), ) encryption_salt = models.CharField( blank=True, max_length=256, verbose_name=_("Encryption salt"), ) minute = models.CharField( max_length=100, default="00", verbose_name=_("Minute"), help_text=_("Values allowed:" "<br>Slider: 0-30 (as it is every Nth minute)." "<br>Specific Minute: 0-59."), ) hour = models.CharField( max_length=100, default="*", verbose_name=_("Hour"), help_text=_("Values allowed:" "<br>Slider: 0-12 (as it is every Nth hour)." "<br>Specific Hour: 0-23."), ) daymonth = models.CharField( max_length=100, default="*", verbose_name=_("Day of month"), help_text=_("Values allowed:" "<br>Slider: 0-15 (as its is every Nth day)." "<br>Specific Day: 1-31."), ) month = models.CharField( max_length=100, default='*', verbose_name=_("Month"), ) dayweek = models.CharField( max_length=100, default="*", verbose_name=_("Day of week"), ) enabled = models.BooleanField( default=True, verbose_name=_("Enabled"), help_text=_( 'Disabling will not stop any syncs which are in progress.'), ) class Meta: verbose_name = _("Cloud Sync") verbose_name_plural = _("Cloud Syncs") ordering = ["description"] def __str__(self): return self.description def get_human_minute(self): if self.minute == '*': return _('Every minute') elif self.minute.startswith('*/'): return _('Every {0} minute(s)').format(self.minute.split('*/')[1]) else: return self.minute def get_human_hour(self): if self.hour == '*': return _('Every hour') elif self.hour.startswith('*/'): return _('Every {0} hour(s)').format(self.hour.split('*/')[1]) else: return self.hour def get_human_daymonth(self): if self.daymonth == '*': return _('Everyday') elif self.daymonth.startswith('*/'): return _('Every {0} days').format(self.daymonth.split('*/')[1]) else: return self.daymonth def get_human_month(self): months = self.month.split(',') if len(months) == 12 or self.month == '*': return _("Every month") mchoices = dict(choices.MONTHS_CHOICES) labels = [] for m in months: labels.append(str(mchoices[m])) return ', '.join(labels) def get_human_dayweek(self): weeks = self.dayweek.split(',') if len(weeks) == 7 or self.dayweek == '*': return _('Everyday') if weeks == list(map(str, range(1, 6))): return _('Weekdays') if weeks == list(map(str, range(6, 8))): return _('Weekends') wchoices = dict(choices.WEEKDAYS_CHOICES) labels = [] for w in weeks: labels.append(str(wchoices[str(w)])) return ', '.join(labels) def run(self): with client as c: jid = c.call('cloudsync.sync', self.id) return jid
class bsdUsers(Model): USERNAME_FIELD = 'bsdusr_username' REQUIRED_FIELDS = [] bsdusr_uid = models.IntegerField( verbose_name=_("User ID"), validators=[MinValueValidator(0), MaxValueValidator(4294967295)], ) bsdusr_username = models.CharField(max_length=16, unique=True, default=_('User &'), verbose_name=_("Username")) bsdusr_unixhash = models.CharField(max_length=128, blank=True, default='*', verbose_name=_("Hashed UNIX password")) bsdusr_smbhash = models.CharField(max_length=128, blank=True, default='*', verbose_name=_("Hashed SMB password")) bsdusr_group = models.ForeignKey(bsdGroups, on_delete=models.SET(get_sentinel_group), verbose_name=_("Primary Group ID")) bsdusr_home = PathField( default="/nonexistent", verbose_name=_("Home Directory"), includes=["/root", "/nonexistent"], ) bsdusr_shell = models.CharField( max_length=120, default='/bin/csh', verbose_name=_("Shell"), choices=choices.SHELL_CHOICES(), ) bsdusr_full_name = models.CharField(max_length=120, verbose_name=_("Full Name")) bsdusr_builtin = models.BooleanField( default=False, editable=False, verbose_name=_("Built-in User"), ) bsdusr_email = models.EmailField(verbose_name=_("E-mail"), blank=True) bsdusr_password_disabled = models.BooleanField( verbose_name=_("Disable password login"), default=False, help_text=_( 'This disables all forms of password login, including for sharing.' ), ) bsdusr_locked = models.BooleanField( verbose_name=_("Lock user"), default=False, ) bsdusr_sudo = models.BooleanField( verbose_name=_("Permit Sudo"), default=False, ) bsdusr_microsoft_account = models.BooleanField( verbose_name=_("Microsoft Account"), default=False) bsdusr_attributes = DictField( default=None, editable=False, ) is_active = True is_staff = True objects = UserManager() @classmethod def has_root_password(cls): qs = cls.objects.filter(bsdusr_uid=0).exclude(bsdusr_unixhash='*') return qs.exists() @property def bsdusr_sshpubkey(self): keysfile = '%s/.ssh/authorized_keys' % self.bsdusr_home if not os.path.exists(keysfile): return '' try: with open(keysfile, 'r') as f: keys = f.read() return keys except: return '' class Meta: verbose_name = _("User") verbose_name_plural = _("Users") ordering = ['bsdusr_builtin', 'bsdusr_username'] def __str__(self): return self.bsdusr_username def get_username(self): "Return the identifying username for this User" return getattr(self, self.USERNAME_FIELD) def natural_key(self): return (self.get_username(), ) @property def is_anonymous(self): """ Always returns False. This is a way of comparing User objects to anonymous users. """ return False @property def is_authenticated(self): """ Always return True. This is a way to tell if the user has been authenticated in templates. """ return True def set_password(self, password): # Django auth backend calls set_password even if user doesnt exist if not self.bsdusr_username or not self.id: time.sleep(0.1) return unixhash, smbhash = notifier().user_changepassword( username=self.bsdusr_username, password=password, ) self.bsdusr_unixhash = unixhash self.bsdusr_smbhash = smbhash def check_password(self, raw_password): # Only allow uid 0 for now if self.bsdusr_uid != 0: return False if self.bsdusr_unixhash: if self.bsdusr_unixhash == 'x' or self.bsdusr_unixhash == '*': return False if isinstance(raw_password, bytes): raw_password = raw_password.decode('utf-8') return crypt.crypt(raw_password, str(self.bsdusr_unixhash)) == str( self.bsdusr_unixhash) def delete(self, using=None, reload=True, delete_group=True): from freenasUI.services.models import CIFS if self.bsdusr_builtin is True: raise ValueError( _("User %s is built-in and can not be deleted!") % (self.bsdusr_username)) notifier().user_deleteuser(self.bsdusr_username) if domaincontroller_enabled(): Samba4().user_delete(self.bsdusr_username) try: gobj = self.bsdusr_group count = bsdGroupMembership.objects.filter( bsdgrpmember_group=gobj).count() count2 = bsdUsers.objects.filter(bsdusr_group=gobj).exclude( id=self.id).count() if delete_group and not gobj.bsdgrp_builtin and count == 0 and count2 == 0: gobj.delete(reload=False, pwdelete=False) except: log.warn('Failed to delete primary group of %s', self, exc_info=True) cifs = CIFS.objects.latest('id') if cifs: if cifs.cifs_srv_guest == self.bsdusr_username: cifs.cifs_srv_guest = 'nobody' cifs.save() super(bsdUsers, self).delete(using) if reload: notifier().reload("user") def save(self, *args, **kwargs): # TODO: Add last_login field if ('update_fields' in kwargs and 'last_login' in kwargs['update_fields']): kwargs['update_fields'].remove('last_login') super(bsdUsers, self).save(*args, **kwargs)