def __init__(self, *args, **kwargs): super(AFP_ShareForm, self).__init__(*args, **kwargs) self.fields['afp_upriv'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_afp_upriv", ["id_afp_fperm", ' '"id_afp_dperm", "id_afp_umask"], true);') self.fields['afp_fperm'] = UnixPermissionField( label=self.fields['afp_fperm'].label, initial=self.fields['afp_fperm'].initial, required=False, ) self.fields['afp_dperm'] = UnixPermissionField( label=self.fields['afp_dperm'].label, initial=self.fields['afp_dperm'].initial, required=False, ) if self.instance.id: if not self.instance.afp_upriv: self.fields['afp_fperm'].widget.attrs['disabled'] = 'true' self.fields['afp_dperm'].widget.attrs['disabled'] = 'true' self.fields['afp_umask'].widget.attrs['disabled'] = 'true' else: self.fields['afp_fperm'].widget.attrs['disabled'] = 'false' self.fields['afp_dperm'].widget.attrs['disabled'] = 'false' self.fields['afp_umask'].widget.attrs['disabled'] = 'false' self.fields['afp_name'].required = False
def __init__(self, *args, **kwargs): super(AFP_ShareForm, self).__init__(*args, **kwargs) self.fields['afp_upriv'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_afp_upriv", ["id_afp_fperm", ' '"id_afp_dperm"], true);') self.fields['afp_fperm'] = UnixPermissionField( label=self.fields['afp_fperm'].label, initial=self.fields['afp_fperm'].initial, required=False, ) self.fields['afp_dperm'] = UnixPermissionField( label=self.fields['afp_dperm'].label, initial=self.fields['afp_dperm'].initial, required=False, ) if self.instance.id: self.fields['afp_sharepw2'].initial = self.instance.afp_sharepw if self.instance.afp_sharepw: self.fields['afp_deletepw'] = forms.BooleanField( label=_("Delete password"), initial=False, required=False, ) self.fields.keyOrder.remove('afp_deletepw') self.fields.keyOrder.insert(5, 'afp_deletepw') if not self.instance.afp_upriv: self.fields['afp_fperm'].widget.attrs['disabled'] = 'true' self.fields['afp_dperm'].widget.attrs['disabled'] = 'true' else: self.fields['afp_fperm'].widget.attrs['disabled'] = 'false' self.fields['afp_dperm'].widget.attrs['disabled'] = 'false'
class FTPForm(MiddlewareModelForm, ModelForm): middleware_attr_prefix = "ftp_" middleware_attr_schema = "ftp" middleware_plugin = "ftp" is_singletone = True ftp_filemask = UnixPermissionField(label=_('File Permission')) ftp_dirmask = UnixPermissionField(label=_('Directory Permission')) class Meta: fields = '__all__' model = models.FTP widgets = { 'ftp_port': forms.widgets.TextInput(), 'ftp_passiveportsmin': forms.widgets.TextInput(), 'ftp_passiveportsmax': forms.widgets.TextInput(), } def __init__(self, *args, **kwargs): if 'instance' in kwargs: instance = kwargs['instance'] try: mask = int(instance.ftp_filemask, 8) instance.ftp_filemask = "%.3o" % (~mask & 0o666) except ValueError: pass try: mask = int(instance.ftp_dirmask, 8) instance.ftp_dirmask = "%.3o" % (~mask & 0o777) except ValueError: pass super(FTPForm, self).__init__(*args, **kwargs) def clean_ftp_filemask(self): perm = self.cleaned_data['ftp_filemask'] perm = int(perm, 8) mask = (~perm & 0o666) return "%.3o" % mask def clean_ftp_dirmask(self): perm = self.cleaned_data['ftp_dirmask'] perm = int(perm, 8) mask = (~perm & 0o777) return "%.3o" % mask
class bsdUsersForm(ModelForm, bsdUserGroupMixin): bsdusr_username = forms.CharField(label=_("Username"), max_length=16) bsdusr_password = forms.CharField(label=_("Password"), widget=forms.PasswordInput, required=False) bsdusr_password2 = forms.CharField( label=_("Password confirmation"), widget=forms.PasswordInput, help_text=_("Enter the same password as above, for verification."), required=False) bsdusr_group = forms.ModelChoiceField( label=_("Primary Group"), queryset=models.bsdGroups.objects.all(), required=False) bsdusr_shell = forms.ChoiceField(label=_("Shell"), initial=u'/bin/csh', choices=()) bsdusr_creategroup = forms.BooleanField( label=_("Create a new primary group for the user"), required=False, initial=True) bsdusr_sshpubkey = forms.CharField(label=_("SSH Public Key"), widget=forms.Textarea, max_length=8192, required=False) bsdusr_mode = UnixPermissionField(label=_('Home Directory Mode'), initial='755', required=False) bsdusr_to_group = SelectMultipleField(label=_('Auxiliary groups'), choices=(), required=False) advanced_fields = ['bsdusr_mode'] class Meta: model = models.bsdUsers widgets = { 'bsdusr_uid': forms.widgets.ValidationTextInput(), } exclude = ( 'bsdusr_unixhash', 'bsdusr_smbhash', 'bsdusr_group', ) fields = ( 'bsdusr_uid', 'bsdusr_username', 'bsdusr_creategroup', 'bsdusr_home', 'bsdusr_mode', 'bsdusr_shell', 'bsdusr_full_name', 'bsdusr_email', 'bsdusr_password', 'bsdusr_password2', 'bsdusr_password_disabled', 'bsdusr_locked', 'bsdusr_sudo', 'bsdusr_sshpubkey', 'bsdusr_to_group', ) def __init__(self, *args, **kwargs): #FIXME: Workaround for DOJO not showing select with blank values if len(args) > 0 and isinstance(args[0], QueryDict): new = args[0].copy() if new.get('bsdusr_group', None) == '-----': new['bsdusr_group'] = '' args = (new, ) + args[1:] super(bsdUsersForm, self).__init__(*args, **kwargs) self.fields.keyOrder.remove('bsdusr_group') self.fields.keyOrder.insert(3, 'bsdusr_group') if self._api is True: del self.fields['bsdusr_password2'] self.fields['bsdusr_shell'].choices = self._populate_shell_choices() self.fields['bsdusr_shell'].choices.sort() self.fields['bsdusr_to_group'].choices = [ (x.id, x.bsdgrp_group) for x in models.bsdGroups.objects.order_by('bsdgrp_group') ] self.fields['bsdusr_password_disabled'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_password_disabled", ' '["id_bsdusr_locked", "id_bsdusr_sudo"], false);') self.fields['bsdusr_locked'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_locked", ' '["id_bsdusr_password_disabled"], false);') self.fields['bsdusr_sudo'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_sudo", ' '["id_bsdusr_password_disabled"], false);') if not self.instance.id: self.fields['bsdusr_uid'].initial = notifier().user_getnextuid() self.fields['bsdusr_home'].label = _('Create Home Directory In') self.fields['bsdusr_creategroup'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_creategroup", ' '["id_bsdusr_group"], false);') self.fields['bsdusr_group'].widget.attrs['maxHeight'] = 200 self.fields['bsdusr_group'].widget.attrs['disabled'] = 'disabled' self.fields['bsdusr_group'].choices = ( ('-----', '-----'), ) + tuple( [x for x in self.fields['bsdusr_group'].choices][1:]) self.fields['bsdusr_group'].required = False self.bsdusr_home_saved = u'/nonexistent' self.bsdusr_home_copy = False elif self.instance.id: self.fields['bsdusr_to_group'].initial = [ x.bsdgrpmember_group.id for x in models.bsdGroupMembership.objects.filter( bsdgrpmember_user=self.instance.id) ] del self.fields['bsdusr_creategroup'] self.fields['bsdusr_group'].initial = self.instance.bsdusr_group self.advanced_fields = [] self.bsdusr_home_saved = self.instance.bsdusr_home self.bsdusr_home_copy = False self.fields.keyOrder.remove('bsdusr_mode') self.fields.keyOrder.insert( len(self.fields.keyOrder) - 1, 'bsdusr_mode', ) self.fields['bsdusr_username'].widget.attrs['readonly'] = True self.fields['bsdusr_username'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') if os.path.exists(self.instance.bsdusr_home): mode = os.stat(self.instance.bsdusr_home).st_mode & 0o777 self.fields['bsdusr_mode'].initial = oct(mode) if self.instance.bsdusr_builtin: self.fields['bsdusr_uid'].widget.attrs['readonly'] = True self.fields['bsdusr_uid'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') self.fields['bsdusr_group'].widget.attrs['readonly'] = True self.fields['bsdusr_group'].widget.attrs['class'] = ( 'dijitDisabled dijitSelectDisabled') self.fields['bsdusr_home'].widget.attrs['readonly'] = True self.fields['bsdusr_home'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') self.fields['bsdusr_mode'].widget.attrs['disabled'] = True self.fields['bsdusr_mode'].required = False if self.instance.bsdusr_locked or self.instance.bsdusr_sudo: self.fields['bsdusr_password_disabled'].widget.attrs[ 'disabled'] = True if self.instance.bsdusr_password_disabled is True: self.fields['bsdusr_locked'].widget.attrs['disabled'] = True self.fields['bsdusr_sudo'].widget.attrs['disabled'] = True self.fields['bsdusr_sshpubkey'].initial = ( self.instance.bsdusr_sshpubkey) def clean_bsdusr_username(self): if self.instance.id is None: bsdusr_username = self.cleaned_data["bsdusr_username"] self.pw_checkname(bsdusr_username) try: models.bsdUsers.objects.get(bsdusr_username=bsdusr_username) except models.bsdUsers.DoesNotExist: return bsdusr_username raise forms.ValidationError( _("A user with that username already exists.")) else: return self.instance.bsdusr_username def clean_bsdusr_uid(self): if self.instance.id and self.instance.bsdusr_builtin: return self.instance.bsdusr_uid else: return self.cleaned_data.get("bsdusr_uid") def clean_bsdusr_group(self): if self.instance.id and self.instance.bsdusr_builtin: return self.instance.bsdusr_group else: create = self.cleaned_data.get("bsdusr_creategroup") group = self.cleaned_data.get("bsdusr_group") if not group and not create: raise forms.ValidationError(_("This field is required")) return group def clean_bsdusr_password(self): bsdusr_password = self.cleaned_data.get('bsdusr_password') # See bug #4098 if bsdusr_password and '?' in bsdusr_password: raise forms.ValidationError( _('Passwords containing a question mark (?) are currently not ' 'allowed due to problems with CIFS.')) return bsdusr_password def clean_bsdusr_password2(self): bsdusr_password = self.cleaned_data.get("bsdusr_password", "") bsdusr_password2 = self.cleaned_data["bsdusr_password2"] if bsdusr_password and bsdusr_password != bsdusr_password2: raise forms.ValidationError( _("The two password fields didn't match.")) return bsdusr_password2 def clean_bsdusr_home(self): home = self.cleaned_data['bsdusr_home'] if self.instance.id and self.instance.bsdusr_uid == 0: return self.instance.bsdusr_home elif home is not None: if ':' in home: raise forms.ValidationError( _("Home directory cannot contain colons")) if home == u'/nonexistent': return home if home.startswith(u'/mnt/'): bsdusr_username = self.cleaned_data.get('bsdusr_username', '') saved_home = self.bsdusr_home_saved if home.endswith(bsdusr_username): if home != saved_home: self.bsdusr_home_copy = True return home if not self.instance.id: home = "%s/%s" % (home.rstrip('/'), bsdusr_username) if not self.instance.id and not home.endswith(bsdusr_username): raise forms.ValidationError( _('Home directory must end with username')) if home != saved_home: self.bsdusr_home_copy = True return home raise forms.ValidationError( _('Home directory has to start with /mnt/ or be /nonexistent')) def clean_bsdusr_mode(self): mode = self.cleaned_data.get('bsdusr_mode') if not self.instance.id and not mode: return '755' return mode def clean_bsdusr_sshpubkey(self): ssh = self.cleaned_data.get('bsdusr_sshpubkey', '') ssh = ssh.strip(' ').strip('\n') ssh = re.sub(r'[ ]{2,}', ' ', ssh, re.M) ssh = re.sub(r'\n{2,}', '\n', ssh, re.M) old = ssh while True: ssh = re.sub(r'(\S{10,})\n(\S{10,})', '\\1\\2', ssh, re.M) if ssh == old: break old = ssh return ssh def clean_bsdusr_full_name(self): name = self.cleaned_data["bsdusr_full_name"] self.pw_checkfullname(name) return name def clean_bsdusr_to_group(self): v = self.cleaned_data.get("bsdusr_to_group") if len(v) > 64: raise forms.ValidationError( _("A user cannot belong to more than 64 auxiliary groups")) return v def clean(self): cleaned_data = self.cleaned_data password_disable = cleaned_data["bsdusr_password_disabled"] = ( cleaned_data.get("bsdusr_password_disabled", False)) bsdusr_home = cleaned_data.get('bsdusr_home', '') if (bsdusr_home and cleaned_data.get('bsdusr_sshpubkey') and (not bsdusr_home.startswith(u'/mnt/') and (self.instance.id is None or (self.instance.id and self.instance.bsdusr_uid != 0)))): del cleaned_data['bsdusr_sshpubkey'] self._errors['bsdusr_sshpubkey'] = self.error_class( [_("Home directory is not writable, leave this blank")]) if self.instance.id is None: FIELDS = ['bsdusr_password', 'bsdusr_password2'] if password_disable: for field in FIELDS: if field in cleaned_data and cleaned_data.get(field) != '': self._errors[field] = self.error_class( [_("Password is disabled, leave this blank")]) del cleaned_data[field] else: for field in FIELDS: if field in cleaned_data and cleaned_data.get(field) == '': self._errors[field] = self.error_class( [_("This field is required.")]) del cleaned_data[field] return cleaned_data def save(self, commit=True): _notifier = notifier() if self.instance.id is None: group = self.cleaned_data['bsdusr_group'] if group is None: try: gid = models.bsdGroups.objects.get( bsdgrp_group=self.cleaned_data['bsdusr_username'] ).bsdgrp_gid except: gid = -1 else: gid = group.bsdgrp_gid uid, gid, unixhash, smbhash = _notifier.user_create( username=str(self.cleaned_data['bsdusr_username']), fullname=self.cleaned_data['bsdusr_full_name'].encode( 'utf8', 'ignore').replace(':', ''), password=self.cleaned_data['bsdusr_password'].encode( 'utf8', 'ignore'), uid=self.cleaned_data['bsdusr_uid'], gid=gid, shell=str(self.cleaned_data['bsdusr_shell']), homedir=str(self.cleaned_data['bsdusr_home']), homedir_mode=int(self.cleaned_data.get('bsdusr_mode', '755'), 8), password_disabled=self.cleaned_data.get( 'bsdusr_password_disabled', False), ) bsduser = super(bsdUsersForm, self).save(commit=False) try: grp = models.bsdGroups.objects.get(bsdgrp_gid=gid) except models.bsdGroups.DoesNotExist: grp = models.bsdGroups( bsdgrp_gid=gid, bsdgrp_group=self.cleaned_data['bsdusr_username'], bsdgrp_builtin=False, ) grp.save() bsduser.bsdusr_group = grp bsduser.bsdusr_uid = uid bsduser.bsdusr_shell = self.cleaned_data['bsdusr_shell'] bsduser.bsdusr_unixhash = unixhash bsduser.bsdusr_smbhash = smbhash bsduser.bsdusr_builtin = False bsduser.save() else: bsduser = super(bsdUsersForm, self).save(commit=False) bsduser.bsdusr_group = self.cleaned_data['bsdusr_group'] bsduser.save() # # Check if updating password # bsdusr_password = self.cleaned_data.get("bsdusr_password", "") if self._api is True: bsdusr_password2 = bsdusr_password else: bsdusr_password2 = self.cleaned_data["bsdusr_password2"] if bsdusr_password and (bsdusr_password == bsdusr_password2): unixhash, smbhash = _notifier.user_changepassword( username=bsduser.bsdusr_username.encode('utf8'), password=bsdusr_password.encode('utf8'), ) bsduser.bsdusr_unixhash = unixhash bsduser.bsdusr_smbhash = smbhash bsduser.save() # # Check if updating group membership # models.bsdGroupMembership.objects.filter( bsdgrpmember_user=bsduser).delete() groupid_list = self.cleaned_data['bsdusr_to_group'] for groupid in groupid_list: group = models.bsdGroups.objects.get(id=groupid) m = models.bsdGroupMembership(bsdgrpmember_group=group, bsdgrpmember_user=bsduser) m.save() _notifier.reload("user") if self.bsdusr_home_copy: p = pipeopen( "su - %s -c '/bin/cp -a %s/* %s/'" % (self.cleaned_data['bsdusr_username'], self.bsdusr_home_saved, self.cleaned_data['bsdusr_home'])) p.communicate() bsdusr_sshpubkey = self.cleaned_data.get('bsdusr_sshpubkey') if bsdusr_sshpubkey: _notifier.save_pubkey(bsduser.bsdusr_home, bsdusr_sshpubkey, bsduser.bsdusr_username, bsduser.bsdusr_group.bsdgrp_group) else: _notifier.delete_pubkey(bsduser.bsdusr_home) return bsduser
class bsdUsersForm(ModelForm): bsdusr_username = forms.CharField(label=_("Username"), max_length=16) bsdusr_password = forms.CharField(label=_("Password"), widget=forms.PasswordInput, required=False) bsdusr_password2 = forms.CharField( label=_("Password confirmation"), widget=forms.PasswordInput, help_text=_("Enter the same password as above, for verification."), required=False) bsdusr_group = forms.ModelChoiceField( label=_("Primary Group"), queryset=models.bsdGroups.objects.all(), required=False) bsdusr_creategroup = forms.BooleanField( label=_("Create a new primary group for the user"), required=False, initial=True) bsdusr_sshpubkey = forms.CharField(label=_("SSH Public Key"), widget=forms.Textarea, required=False) bsdusr_mode = UnixPermissionField(label=_('Home Directory Mode'), initial='755', required=False) bsdusr_to_group = SelectMultipleField(label=_('Auxiliary groups'), choices=(), required=False) advanced_fields = ['bsdusr_mode'] middleware_attr_map = { 'groups': 'bsdusr_to_group', 'group_create': 'bsdusr_creategroup', 'home_mode': 'bsdusr_home', } middleware_attr_prefix = 'bsdusr_' class Meta: model = models.bsdUsers widgets = { 'bsdusr_uid': forms.widgets.ValidationTextInput(), } exclude = ( 'bsdusr_unixhash', 'bsdusr_smbhash', 'bsdusr_group', ) fields = ( 'bsdusr_uid', 'bsdusr_username', 'bsdusr_creategroup', 'bsdusr_home', 'bsdusr_mode', 'bsdusr_shell', 'bsdusr_full_name', 'bsdusr_email', 'bsdusr_password', 'bsdusr_password2', 'bsdusr_password_disabled', 'bsdusr_locked', 'bsdusr_sudo', 'bsdusr_microsoft_account', 'bsdusr_sshpubkey', 'bsdusr_to_group', ) def __init__(self, *args, **kwargs): #FIXME: Workaround for DOJO not showing select with blank values if len(args) > 0 and isinstance(args[0], QueryDict): new = args[0].copy() if new.get('bsdusr_group', None) == '-----': new['bsdusr_group'] = '' args = (new, ) + args[1:] super(bsdUsersForm, self).__init__(*args, **kwargs) key_order(self, 3, 'bsdusr_group', instance=True) if self._api is True: del self.fields['bsdusr_password2'] self.fields['bsdusr_to_group'].choices = [ (x.id, x.bsdgrp_group) for x in models.bsdGroups.objects.all() ] self.fields['bsdusr_password_disabled'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_password_disabled", ' '["id_bsdusr_locked", "id_bsdusr_sudo"], false);') self.fields['bsdusr_locked'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_locked", ' '["id_bsdusr_password_disabled"], false);') self.fields['bsdusr_sudo'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_sudo", ' '["id_bsdusr_password_disabled"], false);') if not self.instance.id: try: with client as c: self.fields['bsdusr_uid'].initial = c.call( 'user.get_next_uid') except Exception: pass self.fields['bsdusr_home'].label = _('Create Home Directory In') self.fields['bsdusr_creategroup'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_creategroup", ' '["id_bsdusr_group"], false);') self.fields['bsdusr_group'].widget.attrs['maxHeight'] = 200 self.fields['bsdusr_group'].widget.attrs['disabled'] = 'disabled' self.fields['bsdusr_group'].choices = ( ('-----', '-----'), ) + tuple( [x for x in self.fields['bsdusr_group'].choices][1:]) self.fields['bsdusr_group'].required = False self.bsdusr_home_saved = '/nonexistent' elif self.instance.id: self.fields['bsdusr_to_group'].initial = [ x.bsdgrpmember_group.id for x in models.bsdGroupMembership.objects.filter( bsdgrpmember_user=self.instance.id) ] del self.fields['bsdusr_creategroup'] self.fields['bsdusr_group'].initial = self.instance.bsdusr_group self.advanced_fields = [] self.bsdusr_home_saved = self.instance.bsdusr_home key_order(self, len(self.fields) - 1, 'bsdusr_mode', instance=True) self.fields['bsdusr_username'].widget.attrs['readonly'] = True self.fields['bsdusr_username'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') if os.path.exists(self.instance.bsdusr_home): mode = os.stat(self.instance.bsdusr_home).st_mode & 0o777 self.fields['bsdusr_mode'].initial = oct(mode)[2:] if self.instance.bsdusr_builtin: self.fields['bsdusr_uid'].widget.attrs['readonly'] = True self.fields['bsdusr_uid'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') self.fields['bsdusr_group'].widget.attrs['readonly'] = True self.fields['bsdusr_group'].widget.attrs['class'] = ( 'dijitDisabled dijitSelectDisabled') self.fields['bsdusr_home'].widget.attrs['readonly'] = True self.fields['bsdusr_home'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') self.fields['bsdusr_mode'].widget.attrs['disabled'] = True self.fields['bsdusr_mode'].required = False if self.instance.bsdusr_locked or self.instance.bsdusr_sudo: self.fields['bsdusr_password_disabled'].widget.attrs[ 'disabled'] = True if self.instance.bsdusr_password_disabled is True: self.fields['bsdusr_locked'].widget.attrs['disabled'] = True self.fields['bsdusr_sudo'].widget.attrs['disabled'] = True self.fields['bsdusr_sshpubkey'].initial = ( self.instance.bsdusr_sshpubkey) def clean_bsdusr_password2(self): bsdusr_password = self.cleaned_data.get("bsdusr_password", "") bsdusr_password2 = self.cleaned_data["bsdusr_password2"] if bsdusr_password and bsdusr_password != bsdusr_password2: raise forms.ValidationError( _("The two password fields didn't match.")) return bsdusr_password2 def clean_bsdusr_home(self): home = self.cleaned_data['bsdusr_home'] user_home = self.instance.bsdusr_home if self.instance.bsdusr_builtin: return self.instance.bsdusr_home if home is not None: if home == '/nonexistent': return home if home.startswith('/mnt/'): bsdusr_username = self.cleaned_data.get('bsdusr_username', '') volumes = [ '/mnt/{}'.format(volume.vol_name) for volume in Volume.objects.all() ] if self.instance.id and home != user_home: if len(zfs.list_datasets(path=user_home)) > 0 and \ (len(zfs.list_datasets(path=home)) > 0 and home.startswith(user_home + '/')): raise forms.ValidationError( _("A dataset inside the home dataset " "cannot be used as a home directory.")) if home in volumes: raise forms.ValidationError( _("Volume root directories cannot be used as user home directories." )) if home.endswith(bsdusr_username): return home if not self.instance.id: home = "%s/%s" % (home.rstrip('/'), bsdusr_username) if not self.instance.id and not home.endswith(bsdusr_username): raise forms.ValidationError( _('Home directory must end with username')) return home def clean_bsdusr_mode(self): mode = self.cleaned_data.get('bsdusr_mode') if not self.instance.id and not mode: return '755' return mode def clean_bsdusr_sshpubkey(self): ssh = self.cleaned_data.get('bsdusr_sshpubkey', '') ssh = ssh.strip(' ').strip('\n') ssh = re.sub(r'[ ]{2,}', ' ', ssh, re.M) ssh = re.sub(r'\n{2,}', '\n', ssh, re.M) old = ssh while True: ssh = re.sub(r'(\S{20,})\n(\S{20,})', '\\1\\2', ssh, re.M) if ssh == old: break old = ssh return ssh def save(self, *args, **kwargs): data = self.cleaned_data.copy() # Convert attributes to new middleware API for k in list(data.keys()): if k.startswith('bsdusr_'): data[k[len('bsdusr_'):]] = data.pop(k) if self.instance.id is None: args = ['user.create'] data['group_create'] = data.pop('creategroup', False) else: args = ['user.update', self.instance.id] # If password is blank, do not send it to middleware if not data.get('password'): data.pop('password', None) data.pop('password2', None) data['home_mode'] = data.pop('mode') if data['group']: data['group'] = data['group'].id else: data.pop('group') data['groups'] = [int(group) for group in data.pop('to_group', [])] if self.instance.bsdusr_builtin: data.pop('home', None) data.pop('home_mode', None) data.pop('uid', None) data.pop('username', None) data.pop('group', None) with client as c: pk = c.call(*args, data) self.instance = models.bsdUsers.objects.get(pk=pk) return self.instance def delete(self, **kwargs): data = { 'delete_group': False if self.data.get('nodelgroup') else True, } with client as c: c.call('user.delete', self.instance.id, data)
class bsdUserChangeForm(ModelForm, bsdUserGroupMixin): bsdusr_mode = UnixPermissionField( label=_('Home Directory Mode'), initial='755', ) bsdusr_shell = forms.ChoiceField( label=_("Shell"), initial=u'/bin/csh', choices=(), ) bsdusr_sshpubkey = forms.CharField( label=_("SSH Public Key"), widget=forms.Textarea, max_length=8192, required=False, ) class Meta: model = models.bsdUsers exclude = ('bsdusr_unixhash', 'bsdusr_smbhash') widgets = { 'bsdusr_uid': forms.widgets.ValidationTextInput(), } def __init__(self, *args, **kwargs): super(bsdUserChangeForm, self).__init__(*args, **kwargs) if self.instance.id: self.fields['bsdusr_username'].widget.attrs['readonly'] = True self.fields['bsdusr_username'].widget.attrs['class'] = ( 'dijitDisabled dijitTextBoxDisabled ' 'dijitValidationTextBoxDisabled') if os.path.exists(self.instance.bsdusr_home): mode = os.stat(self.instance.bsdusr_home).st_mode & 0o777 self.fields['bsdusr_mode'].initial = oct(mode) if self.instance.bsdusr_builtin: self.fields['bsdusr_uid'].widget.attrs['readonly'] = True self.fields['bsdusr_uid'].widget.attrs['class'] = ( 'dijitDisabled' ' dijitTextBoxDisabled dijitValidationTextBoxDisabled') self.fields['bsdusr_group'].widget.attrs['readonly'] = True self.fields['bsdusr_group'].widget.attrs['class'] = ( 'dijitDisabled dijitSelectDisabled') self.fields['bsdusr_home'].widget.attrs['readonly'] = True self.fields['bsdusr_home'].widget.attrs['class'] = ( 'dijitDisabled' ' dijitTextBoxDisabled dijitValidationTextBoxDisabled') try: self.fields['bsdusr_sshpubkey'].initial = open( '%s/.ssh/authorized_keys' % (self.instance.bsdusr_home, )).read() except: self.fields['bsdusr_sshpubkey'].initial = '' self.fields['bsdusr_shell'].choices = self._populate_shell_choices() self.fields['bsdusr_shell'].choices.sort() self.fields['bsdusr_group'].widget.attrs['maxHeight'] = 200 def clean_bsdusr_uid(self): if self.instance.bsdusr_builtin: return self.instance.bsdusr_uid else: return self.cleaned_data.get("bsdusr_uid") def clean_bsdusr_group(self): if self.instance.bsdusr_builtin: return self.instance.bsdusr_group else: return self.cleaned_data.get("bsdusr_group") def clean_bsdusr_username(self): return self.instance.bsdusr_username def clean_bsdusr_home(self): if self.instance.bsdusr_builtin: return self.instance.bsdusr_home if (self.cleaned_data['bsdusr_home'].startswith(u'/mnt/') or self.cleaned_data['bsdusr_home'] == u'/nonexistent'): return self.cleaned_data['bsdusr_home'] raise forms.ValidationError( _('Home directory has to start with /mnt ' 'or be /nonexistent')) def clean_bsdusr_full_name(self): name = self.cleaned_data["bsdusr_full_name"] self.pw_checkfullname(name) return name def clean_bsdusr_password_disabled(self): return self.cleaned_data.get("bsdusr_password_disabled", False) def clean_bsdusr_locked(self): return self.cleaned_data.get("bsdusr_locked", False) def clean(self): cleaned_data = self.cleaned_data bsdusr_home = self.cleaned_data.get('bsdusr_home', '') if (bsdusr_home and cleaned_data.get('bsdusr_sshpubkey') and not (bsdusr_home.startswith(u'/mnt/') or bsdusr_home == '/root')): del cleaned_data['bsdusr_sshpubkey'] self._errors['bsdusr_sshpubkey'] = self.error_class([ _("Home directory is not writable, leave this blank"), ]) return cleaned_data def save(self): bsduser = super(bsdUserChangeForm, self).save(commit=False) bsdusr_sshpubkey = self.cleaned_data['bsdusr_sshpubkey'] _notifier = notifier() bsduser.bsduser_shell = self.cleaned_data['bsdusr_shell'] if os.path.exists(self.cleaned_data['bsdusr_home']) and \ self.cleaned_data['bsdusr_home'].startswith(u'/mnt/'): try: os.chmod(self.cleaned_data['bsdusr_home'], int(self.cleaned_data['bsdusr_mode'], 8)) except OSError, e: log.info( "Failed to set permission in home dir %s: %s", self.cleaned_data['bsdusr_home'], e, ) bsduser.save() _notifier.reload("user") if (self.cleaned_data['bsdusr_home'].startswith(u'/mnt/') or self.cleaned_data['bsdusr_home'] == '/root'): if bsdusr_sshpubkey: _notifier.save_pubkey(bsduser.bsdusr_home, bsdusr_sshpubkey, bsduser.bsdusr_username, bsduser.bsdusr_group.bsdgrp_group) return bsduser
class bsdUserCreationForm(ModelForm, bsdUserGroupMixin): """ # Yanked from django/contrib/auth/ A form that creates a user, with no privileges, from the given username and password. """ bsdusr_username = forms.CharField(label=_("Username"), max_length=16) bsdusr_password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput, required=False) bsdusr_password2 = forms.CharField( label=_("Password confirmation"), widget=forms.PasswordInput, help_text=_("Enter the same password as above, for verification."), required=False) bsdusr_shell = forms.ChoiceField(label=_("Shell"), initial=u'/bin/csh', choices=()) bsdusr_creategroup = forms.BooleanField( label=_("Create a new primary group for the user"), required=False, initial=True) bsdusr_group2 = forms.ModelChoiceField( label=_("Primary Group"), queryset=models.bsdGroups.objects.all(), required=False) bsdusr_sshpubkey = forms.CharField(label=_("SSH Public Key"), widget=forms.Textarea, max_length=8192, required=False) bsdusr_mode = UnixPermissionField(label=_('Home Directory Mode'), initial='755') bsdusr_to_group = FilteredSelectField(label=_('Auxiliary groups'), choices=(), required=False) advanced_fields = ['bsdusr_mode'] class Meta: model = models.bsdUsers widgets = { 'bsdusr_uid': forms.widgets.ValidationTextInput(), } exclude = ( 'bsdusr_unixhash', 'bsdusr_smbhash', 'bsdusr_group', ) fields = ( 'bsdusr_uid', 'bsdusr_username', 'bsdusr_creategroup', 'bsdusr_group2', 'bsdusr_home', 'bsdusr_mode', 'bsdusr_shell', 'bsdusr_full_name', 'bsdusr_email', 'bsdusr_password1', 'bsdusr_password2', 'bsdusr_password_disabled', 'bsdusr_sshpubkey', 'bsdusr_locked', 'bsdusr_to_group', ) def __init__(self, *args, **kwargs): #FIXME: Workaround for DOJO not showing select with blank values if len(args) > 0 and isinstance(args[0], QueryDict): new = args[0].copy() if new.get('bsdusr_group2', None) == '-----': new['bsdusr_group2'] = '' args = (new, ) + args[1:] super(bsdUserCreationForm, self).__init__(*args, **kwargs) self.fields['bsdusr_shell'].choices = self._populate_shell_choices() self.fields['bsdusr_shell'].choices.sort() self.fields['bsdusr_uid'].initial = notifier().user_getnextuid() self.fields['bsdusr_creategroup'].widget.attrs['onChange'] = ( 'javascript:toggleGeneric("id_bsdusr_creategroup", ' '["id_bsdusr_group2"], false);') self.fields['bsdusr_group2'].widget.attrs['maxHeight'] = 200 self.fields['bsdusr_group2'].widget.attrs['disabled'] = 'disabled' self.fields['bsdusr_group2'].choices = (('-----', '-----'), ) + tuple( [x for x in self.fields['bsdusr_group2'].choices][1:]) self.fields['bsdusr_group2'].required = False self.fields['bsdusr_to_group'].choices = [(x.id, x.bsdgrp_group) \ for x in models.bsdGroups.objects.all()] def clean_bsdusr_username(self): if self.instance.id is None: bsdusr_username = self.cleaned_data["bsdusr_username"] self.pw_checkname(bsdusr_username) try: models.bsdUsers.objects.get(bsdusr_username=bsdusr_username) except models.bsdUsers.DoesNotExist: return bsdusr_username raise forms.ValidationError( _("A user with that username already exists.")) else: return self.instance.bsdusr_username def clean_bsdusr_group2(self): create = self.cleaned_data.get("bsdusr_creategroup") group = self.cleaned_data.get("bsdusr_group2") if not group and not create: raise forms.ValidationError(_("This field is required")) return group def clean_bsdusr_password2(self): bsdusr_password1 = self.cleaned_data.get("bsdusr_password1", "") bsdusr_password2 = self.cleaned_data["bsdusr_password2"] if bsdusr_password1 != bsdusr_password2: raise forms.ValidationError( _("The two password fields didn't match.")) return bsdusr_password2 def clean_bsdusr_home(self): home = self.cleaned_data['bsdusr_home'] if ':' in home: raise forms.ValidationError( _("Home directory cannot contain colons")) if home.startswith(u'/mnt/') or home == u'/nonexistent': return home raise forms.ValidationError( _('Home directory has to start with /mnt/ or be /nonexistent')) def clean_bsdusr_sshpubkey(self): return self.cleaned_data.get('bsdusr_sshpubkey', '') def clean_bsdusr_full_name(self): name = self.cleaned_data["bsdusr_full_name"] self.pw_checkfullname(name) return name def clean_bsdusr_to_group(self): v = self.cleaned_data.get("bsdusr_to_group") if len(v) > 64: raise forms.ValidationError( _("A user cannot belong to more than 64 auxiliary groups")) return v def clean(self): cleaned_data = self.cleaned_data password_disable = cleaned_data["bsdusr_password_disabled"] = \ cleaned_data.get("bsdusr_password_disabled", False) bsdusr_home = cleaned_data.get('bsdusr_home', '') if (bsdusr_home and cleaned_data.get('bsdusr_sshpubkey') and not bsdusr_home.startswith(u'/mnt/')): del cleaned_data['bsdusr_sshpubkey'] self._errors['bsdusr_sshpubkey'] = self.error_class( [_("Home directory is not writable, leave this blank")]) if self.instance.id is None: FIELDS = ['bsdusr_password1', 'bsdusr_password2'] if password_disable: for field in FIELDS: if field in cleaned_data and cleaned_data.get(field) != '': self._errors[field] = self.error_class( [_("Password is disabled, leave this blank")]) del cleaned_data[field] else: for field in FIELDS: if field in cleaned_data and cleaned_data.get(field) == '': self._errors[field] = self.error_class( [_("This field is required.")]) del cleaned_data[field] return cleaned_data def save(self, commit=True): if commit: _notifier = notifier() group = self.cleaned_data['bsdusr_group2'] if group is None: try: gid = models.bsdGroups.objects.get( bsdgrp_group=self.cleaned_data['bsdusr_username'] ).bsdgrp_gid except: gid = -1 else: gid = group.bsdgrp_gid uid, gid, unixhash, smbhash = _notifier.user_create( username=str(self.cleaned_data['bsdusr_username']), fullname=self.cleaned_data['bsdusr_full_name'].encode( 'utf8', 'ignore').replace(':', ''), password=self.cleaned_data['bsdusr_password2'].encode( 'utf8', 'ignore'), uid=self.cleaned_data['bsdusr_uid'], gid=gid, shell=str(self.cleaned_data['bsdusr_shell']), homedir=str(self.cleaned_data['bsdusr_home']), homedir_mode=int(self.cleaned_data['bsdusr_mode'], 8), password_disabled=self.cleaned_data.get( 'bsdusr_password_disabled', False), ) bsduser = super(bsdUserCreationForm, self).save(commit=False) try: grp = models.bsdGroups.objects.get(bsdgrp_gid=gid) except models.bsdGroups.DoesNotExist: grp = models.bsdGroups( bsdgrp_gid=gid, bsdgrp_group=self.cleaned_data['bsdusr_username'], bsdgrp_builtin=False, ) grp.save() bsduser.bsdusr_group = grp bsduser.bsdusr_uid = uid bsduser.bsdusr_shell = self.cleaned_data['bsdusr_shell'] bsduser.bsdusr_unixhash = unixhash bsduser.bsdusr_smbhash = smbhash bsduser.bsdusr_builtin = False bsduser.save() models.bsdGroupMembership.objects.filter( bsdgrpmember_user=bsduser).delete() groupid_list = self.cleaned_data['bsdusr_to_group'] for groupid in groupid_list: group = models.bsdGroups.objects.get(id=groupid) m = models.bsdGroupMembership(bsdgrpmember_group=group, bsdgrpmember_user=bsduser) m.save() _notifier.reload("user") bsdusr_sshpubkey = self.cleaned_data.get('bsdusr_sshpubkey') if bsdusr_sshpubkey: _notifier.save_pubkey(bsduser.bsdusr_home, bsdusr_sshpubkey, bsduser.bsdusr_username, bsduser.bsdusr_group.bsdgrp_group) return bsduser