Beispiel #1
0
class RegistroUsuario(ModelSoftlogView):
    route_base = '/registeruser'
    list_widget = ListWidget
    base_order = ('username', 'asc')

    base_permissions = ['Listar', 'Visualizar', 'Excluir']
    list_title = lazy_gettext('List of Registration Requests')
    show_title = lazy_gettext('Show Registration')
    list_columns = ['username', 'registration_date', 'email']
    show_exclude_columns = ['password']
    search_exclude_columns = ['password']
Beispiel #2
0
class Menus(ModelSoftlogView):
    route_base = '/viewmenus'
    base_permissions = ['Listar']
    list_widget = ListWidget
    base_order = ('name', 'asc')
    start_empty = False

    list_title = lazy_gettext('List View Menus')
    show_title = lazy_gettext('Show View Menu')
    add_title = lazy_gettext('Add View Menu')
    edit_title = lazy_gettext('Edit View Menu')

    label_columns = {'name': lazy_gettext('Name')}
Beispiel #3
0
class TipoPermissoes(ModelSoftlogView):
    route_base = '/permissions'
    base_permissions = ['Listar']
    list_widget = ListWidget
    start_empty = False
    base_order = ('name', 'asc')

    list_title = lazy_gettext('List Base Permissions')
    show_title = lazy_gettext('Show Base Permission')
    add_title = lazy_gettext('Add Base Permission')
    edit_title = lazy_gettext('Edit Base Permission')

    label_columns = {'name': lazy_gettext('Name')}
Beispiel #4
0
class RedefinirSenha(SimpleFormView):
    """
        View for reseting all users password
    """
    route_base = '/resetpassword'
    form = ResetPasswordForm
    form_title = lazy_gettext('Reset Password Form')
    redirect_url = '/'
    message = lazy_gettext('Password Changed')

    def form_post(self, form):
        pk = request.args.get('pk')
        self.appbuilder.sm.reset_password(pk, form.password.data)
        flash(as_unicode(self.message), 'info')
Beispiel #5
0
class RedefinirMinhaSenha(SimpleFormView):
    """
        View for resetting own user password
    """
    route_base = '/resetmypassword'

    form = ResetPasswordForm
    form_title = lazy_gettext('Reset Password Form')
    redirect_url = '/'
    message = lazy_gettext('Password Changed')

    def form_post(self, form):
        self.appbuilder.sm.reset_password(g.user.id, form.password.data)
        flash(as_unicode(self.message), 'info')
Beispiel #6
0
class GruposUsuario(ModelSoftlogView):
    route_base = '/roles'
    list_widget = ListWidget
    base_order = ('name', 'asc')
    start_empty = False

    list_title = lazy_gettext('List Roles')
    show_title = lazy_gettext('Show Role')
    add_title = lazy_gettext('Add Role')
    edit_title = lazy_gettext('Edit Role')

    label_columns = {
        'name': lazy_gettext('Name'),
        'permissions': lazy_gettext('Permissions')
    }
    list_columns = ['name', 'permissions']
    order_columns = ['name']

    @action("Clonar Grupo",
            lazy_gettext('Copy Role'),
            lazy_gettext('Copy the selected roles?'),
            icon='fa-copy',
            single=False)
    def copy_role(self, items):
        self.update_redirect()
        for item in items:
            new_role = item.__class__()
            new_role.name = item.name
            new_role.permissions = item.permissions
            new_role.name = new_role.name + ' copiar'
            self.datamodel.add(new_role)
        return redirect(self.get_redirect())
Beispiel #7
0
class FilterNotStartsWith(BaseFilter):
    name = lazy_gettext('Not Starts with')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        return query.filter(~field.like(value + '%'))
Beispiel #8
0
class FilterNotContains(BaseFilter):
    name = lazy_gettext('Not Contains')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        return query.filter(~field.like('%' + value + '%'))
Beispiel #9
0
class FilterEndsWith(BaseFilter):
    name = lazy_gettext('Ends with')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        return query.filter(field.like('%' + value))
Beispiel #10
0
class FilterRelationOneToManyNotEqual(FilterRelation):
    name = lazy_gettext('No Relation')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        rel_obj = self.datamodel.get_related_obj(self.column_name, value)
        return query.filter(field != rel_obj)
Beispiel #11
0
class FilterSmaller(BaseFilter):
    name = lazy_gettext('Smaller than')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        value = set_value_to_type(self.datamodel, self.column_name, value)
        return query.filter(field < value)
Beispiel #12
0
class FilterNotEqual(BaseFilter):
    name = lazy_gettext('Not Equal to')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        value = set_value_to_type(self.datamodel, self.column_name, value)
        return query.filter(field != value)
Beispiel #13
0
class FilterRelationManyToManyEqual(FilterRelation):
    name = lazy_gettext('Relation as Many')

    def apply(self, query, value):
        query, field = get_field_setup_query(query, self.model,
                                             self.column_name)
        rel_obj = self.datamodel.get_related_obj(self.column_name, value)
        return query.filter(field.contains(rel_obj))
Beispiel #14
0
class StringConexoesView(ModelSoftlogView):
    route_base = '/databases_tenancy'
    base_permissions = ['Listar', 'Visualizar']
    list_columns = ['banco_dados', 'host', 'port']

    list_title = lazy_gettext('List Base Permissions')
    show_title = lazy_gettext('Show Base Permission')
    add_title = lazy_gettext('Add Base Permission')
    edit_title = lazy_gettext('Edit Base Permission')

    label_columns = {
        'id_string_conexao': lazy_gettext('Id'),
        'banco_dados': lazy_gettext('DataBase'),
        'usuario': lazy_gettext('User'),
        'senha': lazy_gettext('Password'),
        'port': lazy_gettext('Port'),
        'host': lazy_gettext('Host')
    }
Beispiel #15
0
class UsuarioInformacoes(SimpleFormView):
    form = UserInfoEdit
    form_title = lazy_gettext('Edit User Information')
    redirect_url = '/'
    message = lazy_gettext('User information changed')

    def form_get(self, form):
        item = self.appbuilder.sm.get_user_by_id(g.user.id)
        # fills the form generic solution
        for key, value in form.data.items():
            form_field = getattr(form, key)
            form_field.data = getattr(item, key)

    def form_post(self, form):
        form = self.form.refresh(request.form)
        item = self.appbuilder.sm.get_user_by_id(g.user.id)
        form.populate_obj(item)
        self.appbuilder.sm.update_user(item)
        flash(as_unicode(self.message), 'info')
Beispiel #16
0
class UsuarioEstatisticas(DirectByChartView):
    chart_title = lazy_gettext('User Statistics')
    label_columns = {
        'username': lazy_gettext('User Name'),
        'login_count': lazy_gettext('Login count'),
        'fail_login_count': lazy_gettext('Failed login count')
    }

    search_columns = UserModelView.search_columns

    definitions = [{
        'label': 'Login Count',
        'group': 'username',
        'series': ['login_count']
    }, {
        'label': 'Failed Login Count',
        'group': 'username',
        'series': ['fail_login_count']
    }]
Beispiel #17
0
class AuthView(BaseView):
    route_base = ''
    login_template = ''

    invalid_login_message = lazy_gettext('Invalid login. Please try again.')

    title = lazy_gettext('Sign In')

    @expose('/login/', methods=['GET', 'POST'])
    def login(self):
        pass

    @expose('/logout/')
    def logout(self):
        logout_user()
        return redirect(self.appbuilder.get_url_for_index)

    @expose('/relogin/', methods=['GET', 'POST'])
    def relogin(self):
        pass
Beispiel #18
0
class Permissoes(ModelSoftlogView):
    route_base = '/permissionviews'
    base_permissions = ['Listar']
    list_widget = ListWidget
    start_empty = False

    list_title = lazy_gettext('List Permissions on Views/Menus')
    show_title = lazy_gettext('Show Permission on Views/Menus')
    add_title = lazy_gettext('Add Permission on Views/Menus')
    edit_title = lazy_gettext('Edit Permission on Views/Menus')

    label_columns = {
        'permission': lazy_gettext('Permission'),
        'view_menu': lazy_gettext('View/Menu')
    }
    list_columns = ['permission', 'view_menu']
Beispiel #19
0
class BaseRegisterUser(PublicFormView):
    """
        Make your own user registration view and inherit from this class if you
        want to implement a completely different registration process. If not,
        just inherit from RegisterUserDBView or RegisterUserOIDView depending on
        your authentication method.
        then override SecurityManager property that defines the class to use::

            from flask.ext.appbuilder.security.registerviews import RegisterUserDBView

            class MyRegisterUserDBView(BaseRegisterUser):
                email_template = 'register_mail.html'
                ...


            class MySecurityManager(SecurityManager):
               registeruserdbview = MyRegisterUserDBView

        When instantiating AppBuilder set your own SecurityManager class::

            appbuilder = AppBuilder(app, db.session, security_manager_class=MySecurityManager)
    """
    route_base = '/register'
    email_template = 'appbuilder/general/security/register_mail.html'
    """ The template used to generate the email sent to the user """
    email_subject = lazy_gettext('Account activation')
    """ The email subject sent to the user """
    activation_template = 'appbuilder/general/security/activation.html'
    """ The activation template, shown when the user is activated """
    message = lazy_gettext('Registration sent to your email')
    """ The message shown on a successful registration """
    error_message = lazy_gettext(
        'Not possible to register you at the moment, try again later')
    """ The message shown on an unsuccessful registration """
    false_error_message = lazy_gettext('Registration not found')
    """ The message shown on an unsuccessful registration """
    form_title = lazy_gettext('Fill out the registration form')
    """ The form title """
    def send_email(self, register_user):
        """
            Method for sending the registration Email to the user
        """
        try:
            from flask_mail import Mail, Message
        except:
            log.error("Install Flask-Mail to use User registration")
            return False
        mail = Mail(self.appbuilder.get_app)
        msg = Message()
        msg.subject = self.email_subject
        url = url_for('.activation',
                      _external=True,
                      activation_hash=register_user.registration_hash)
        msg.html = self.render_template(self.email_template,
                                        url=url,
                                        username=register_user.username,
                                        first_name=register_user.first_name,
                                        last_name=register_user.last_name)
        msg.recipients = [register_user.email]
        try:
            mail.send(msg)
        except Exception as e:
            log.error("Send email exception: {0}".format(str(e)))
            return False
        return True

    def add_registration(self,
                         username,
                         first_name,
                         last_name,
                         email,
                         password=''):
        """
            Add a registration request for the user.

        :rtype : RegisterUser
        """
        register_user = self.appbuilder.sm.add_register_user(
            username, first_name, last_name, email, password)
        if register_user:
            if self.send_email(register_user):
                flash(as_unicode(self.message), 'info')
                return register_user
            else:
                flash(as_unicode(self.error_message), 'danger')
                self.appbuilder.sm.del_register_user(register_user)
                return None

    @expose('/activation/<string:activation_hash>')
    def activation(self, activation_hash):
        """
            Endpoint to expose an activation url, this url
            is sent to the user by email, when accessed the user is inserted
            and activated
        """
        reg = self.appbuilder.sm.find_register_user(activation_hash)
        if not reg:
            log.error(
                c.LOGMSG_ERR_SEC_NO_REGISTER_HASH.format(activation_hash))
            flash(as_unicode(self.false_error_message), 'danger')
            return redirect(self.appbuilder.get_url_for_index)
        if not self.appbuilder.sm.add_user(
                username=reg.username,
                email=reg.email,
                first_name=reg.first_name,
                last_name=reg.last_name,
                role=self.appbuilder.sm.find_role(
                    self.appbuilder.sm.auth_user_registration_role),
                hashed_password=reg.password):
            flash(as_unicode(self.error_message), 'danger')
            return redirect(self.appbuilder.get_url_for_index)
        else:
            self.appbuilder.sm.del_register_user(reg)
            return self.render_template(self.activation_template,
                                        username=reg.username,
                                        first_name=reg.first_name,
                                        last_name=reg.last_name,
                                        appbuilder=self.appbuilder)

    def add_form_unique_validations(self, form):
        datamodel_user = self.appbuilder.sm.get_user_datamodel
        datamodel_register_user = self.appbuilder.sm.get_register_user_datamodel
        if len(form.username.validators) == 1:
            form.username.validators.append(Unique(datamodel_user, 'username'))
            form.username.validators.append(
                Unique(datamodel_register_user, 'username'))
        if len(form.email.validators) == 2:
            form.email.validators.append(Unique(datamodel_user, 'email'))
            form.email.validators.append(
                Unique(datamodel_register_user, 'email'))
Beispiel #20
0
class BaseInterface(object):
    """
        Base class for all data model interfaces.
        Sub class it to implement your own interface for some data engine.
    """
    obj = None

    filter_converter_class = None
    """ when sub classing override with your own custom filter converter """
    """ Messages to display on CRUD Events """
    add_row_message = lazy_gettext('Added Row')
    edit_row_message = lazy_gettext('Changed Row')
    delete_row_message = lazy_gettext('Deleted Row')
    delete_integrity_error_message = lazy_gettext(
        'Associated data exists, please delete them first')
    add_integrity_error_message = lazy_gettext(
        'Integrity error, probably unique constraint')
    edit_integrity_error_message = lazy_gettext(
        'Integrity error, probably unique constraint')
    general_error_message = lazy_gettext('General Error')
    """ Tuple with message and text with severity type ex: ("Added Row", "info") """
    message = ()

    def __init__(self, obj):
        self.obj = obj

    def _get_attr_value(self, item, col):
        if not hasattr(item, col):
            # it's an inner obj attr
            try:
                return reduce(getattr, col.split('.'), item)
            except Exception as e:
                return ''
        if hasattr(getattr(item, col), '__call__'):
            # its a function
            return getattr(item, col)()
        else:
            # its an attribute
            return getattr(item, col)

    def get_filters(self, search_columns=None):
        search_columns = search_columns or []
        return Filters(self.filter_converter_class, self, search_columns)

    def get_values_item(self, item, show_columns):
        return [self._get_attr_value(item, col) for col in show_columns]

    def _get_values(self, lst, list_columns):
        """
            Get Values: formats values for list template.
            returns [{'col_name':'col_value',....},{'col_name':'col_value',....}]

            :param lst:
                The list of item objects from query
            :param list_columns:
                The list of columns to include
        """
        retlst = []
        for item in lst:
            retdict = {}
            for col in list_columns:
                retdict[col] = self._get_attr_value(item, col)
            retlst.append(retdict)
        return retlst

    def get_values(self, lst, list_columns):
        """
            Get Values: formats values for list template.
            returns [{'col_name':'col_value',....},{'col_name':'col_value',....}]

            :param lst:
                The list of item objects from query
            :param list_columns:
                The list of columns to include
        """
        for item in lst:
            retdict = {}
            for col in list_columns:
                retdict[col] = self._get_attr_value(item, col)
            yield retdict

    def get_values_json(self, lst, list_columns):
        """
            Converts list of objects from query to JSON
        """
        result = []
        for item in self.get_values(lst, list_columns):
            for key, value in list(item.items()):
                if isinstance(value, datetime.datetime) or isinstance(
                        value, datetime.date):
                    value = value.isoformat()
                    item[key] = value
                if isinstance(value, list):
                    item[key] = [str(v) for v in value]
            result.append(item)
        return result

    """
        Returns the models class name
        useful for auto title on views
    """

    @property
    def model_name(self):
        return self.obj.__class__.__name__

    """
        Next methods must be overridden
    """

    def query(self,
              filters=None,
              order_column='',
              order_direction='',
              page=None,
              page_size=None):
        pass

    def is_image(self, col_name):
        return False

    def is_file(self, col_name):
        return False

    def is_gridfs_file(self, col_name):
        return False

    def is_gridfs_image(self, col_name):
        return False

    def is_string(self, col_name):
        return False

    def is_text(self, col_name):
        return False

    def is_integer(self, col_name):
        return False

    def is_numeric(self, col_name):
        return False

    def is_float(self, col_name):
        return False

    def is_boolean(self, col_name):
        return False

    def is_date(self, col_name):
        return False

    def is_datetime(self, col_name):
        return False

    def is_relation(self, prop):
        return False

    def is_relation_col(self, col):
        return False

    def is_relation_many_to_one(self, prop):
        return False

    def is_relation_many_to_many(self, prop):
        return False

    def is_relation_one_to_one(self, prop):
        return False

    def is_relation_one_to_many(self, prop):
        return False

    def is_nullable(self, col_name):
        return True

    def is_unique(self, col_name):
        return False

    def is_pk(self, col_name):
        return False

    def is_fk(self, col_name):
        return False

    def get_max_length(self, col_name):
        return -1

    def get_min_length(self, col_name):
        return -1

    """
    -----------------------------------------
           FUNCTIONS FOR CRUD OPERATIONS
    -----------------------------------------
    """

    def add(self, item):
        """
            Adds object
        """
        raise NotImplementedError

    def edit(self, item):
        """
            Edit (change) object
        """
        raise NotImplementedError

    def delete(self, item):
        """
            Deletes object
        """
        raise NotImplementedError

    def get_col_default(self, col_name):
        pass

    def get_keys(self, lst):
        """
            return a list of pk values from object list
        """
        pk_name = self.get_pk_name()
        return [getattr(item, pk_name) for item in lst]

    def get_pk_name(self, item):
        """
            Returns the primary key name
        """
        raise NotImplementedError

    def get_pk_value(self, item):
        return getattr(item, self.get_pk_name())

    def get(self, pk, filter=None):
        """
            return the record from key, you can optionally pass filters
            if pk exits on the db but filters exclude it it will return none.
        """
        pass

    def get_related_model(self, prop):
        raise NotImplementedError

    def get_related_interface(self, col_name):
        """
            Returns a BaseInterface for the related model
            of column name.

            :param col_name: Column name with relation
            :return: BaseInterface
        """
        raise NotImplementedError

    def get_related_obj(self, col_name, value):
        raise NotImplementedError

    def get_related_fk(self, model):
        raise NotImplementedError

    def get_columns_list(self):
        """
            Returns a list of all the columns names
        """
        return []

    def get_user_columns_list(self):
        """
            Returns a list of user viewable columns names
        """
        return self.get_columns_list()

    def get_search_columns_list(self):
        """
            Returns a list of searchable columns names
        """
        return []

    def get_order_columns_list(self, list_columns=None):
        """
            Returns a list of order columns names
        """
        return []

    def get_relation_fk(self, prop):
        pass
Beispiel #21
0
class UserModelView(ModelSoftlogView):
    route_base = '/users'
    list_widget = ListWidget
    start_empty = False

    list_title = lazy_gettext('List Users')
    show_title = lazy_gettext('Show User')
    add_title = lazy_gettext('Add User')
    edit_title = lazy_gettext('Edit User')
    base_order = ("first_name", "asc")

    label_columns = {
        'get_full_name': lazy_gettext('Full Name'),
        'first_name': lazy_gettext('First Name'),
        'last_name': lazy_gettext('Last Name'),
        'username': lazy_gettext('User Name'),
        'password': lazy_gettext('Password'),
        'active': lazy_gettext('Is Active?'),
        'email': lazy_gettext('EMail'),
        'roles': lazy_gettext('Role'),
        'last_login': lazy_gettext('Last login'),
        'login_count': lazy_gettext('Login count'),
        'fail_login_count': lazy_gettext('Failed login count'),
        'created_on': lazy_gettext('Created on'),
        'created_by': lazy_gettext('Created by'),
        'changed_on': lazy_gettext('Changed on'),
        'changed_by': lazy_gettext('Changed by')
    }

    description_columns = {
        'first_name':
        lazy_gettext('Write the user first name or names'),
        'last_name':
        lazy_gettext('Write the user last name'),
        'username':
        lazy_gettext(
            'Username valid for authentication on DB or LDAP, unused for OID auth'
        ),
        'password':
        lazy_gettext(
            'Please use a good password policy, this application does not check this for you'
        ),
        'active':
        lazy_gettext(
            'It\'s not a good policy to remove a user, just make it inactive'),
        'email':
        lazy_gettext('The user\'s email, this will also be used for OID auth'),
        'roles':
        lazy_gettext(
            'The user role on the application, this will associate with a list of permissions'
        ),
        'conf_password':
        lazy_gettext('Please rewrite the user\'s password to confirm')
    }

    list_columns = [
        'nome_usuario', 'last_name', 'username', 'email', 'active', 'roles'
    ]

    show_fieldsets = [
        (lazy_gettext('User info'), {
            'fields': ['username', 'active', 'roles', 'login_count']
        }),
        (lazy_gettext('Personal Info'), {
            'fields': ['first_name', 'last_name', 'email'],
            'expanded': True
        }),
        (lazy_gettext('Audit Info'), {
            'fields': [
                'last_login', 'fail_login_count', 'created_on', 'created_by',
                'changed_on', 'changed_by'
            ],
            'expanded':
            False
        }),
    ]

    user_show_fieldsets = [
        (lazy_gettext('User info'), {
            'fields': ['username', 'active', 'roles', 'login_count']
        }),
        (lazy_gettext('Personal Info'), {
            'fields': ['first_name', 'last_name', 'email'],
            'expanded': True
        }),
    ]

    search_exclude_columns = ['password']

    add_columns = [
        'nome_usuario', 'last_name', 'username', 'active', 'email', 'roles'
    ]
    edit_columns = [
        'nome_usuario', 'last_name', 'username', 'active', 'email', 'roles'
    ]
    user_info_title = lazy_gettext("Your user information")

    @expose('/userinfo/')
    @has_access
    def userinfo(self):
        item = self.datamodel.get(g.user.id, self._base_filters)
        widgets = self._get_show_widget(
            g.user.id, item, show_fieldsets=self.user_show_fieldsets)
        self.update_redirect()
        return self.render_template(self.show_template,
                                    title=self.user_info_title,
                                    widgets=widgets,
                                    appbuilder=self.appbuilder)

    @action('userinfoedit',
            lazy_gettext("Edit User"),
            "",
            "fa-edit",
            multiple=False)
    def userinfoedit(self, item):
        return redirect(
            url_for(self.appbuilder.sm.userinfoeditview.__name__ +
                    '.this_form_get'))
Beispiel #22
0
class Usuarios(UserModelView):
    """
        View that add DB specifics to User view.
        Override to implement your own custom view.
        Then override userdbmodelview property on SecurityManager
    """
    add_form_extra_fields = {
        'password':
        PasswordField(
            lazy_gettext('Password'),
            description=lazy_gettext(
                'Please use a good password policy, this application does not check this for you'
            ),
            validators=[validators.DataRequired()],
            widget=BS3PasswordFieldWidget()),
        'conf_password':
        PasswordField(lazy_gettext('Confirm Password'),
                      description=lazy_gettext(
                          'Please rewrite the user\'s password to confirm'),
                      validators=[
                          EqualTo('password',
                                  message=lazy_gettext('Passwords must match'))
                      ],
                      widget=BS3PasswordFieldWidget())
    }

    add_columns = [
        'nome_usuario', 'last_name', 'username', 'active', 'email', 'roles',
        'password', 'conf_password'
    ]

    @expose('/show/<pk>', methods=['GET'])
    @has_access
    @permission_name("Visualizar")
    def show(self, pk):
        actions = {}
        actions['resetpasswords'] = self.actions.get('resetpasswords')
        item = self.datamodel.get(pk, self._base_filters)
        if not item:
            abort(404)
        widgets = self._get_show_widget(pk, item, actions=actions)
        self.update_redirect()
        return self.render_template(self.show_template,
                                    pk=pk,
                                    title=self.show_title,
                                    widgets=widgets,
                                    appbuilder=self.appbuilder,
                                    related_views=self._related_views)

    @expose('/userinfo/')
    @has_access
    @permission_name("InformacaoUsuario")
    def userinfo(self):
        actions = {}
        actions['resetmypassword'] = self.actions.get('resetmypassword')
        actions['userinfoedit'] = self.actions.get('userinfoedit')

        item = self.datamodel.get(g.user.id, self._base_filters)
        widgets = self._get_show_widget(
            g.user.id,
            item,
            actions=actions,
            show_fieldsets=self.user_show_fieldsets)
        self.update_redirect()
        return self.render_template(
            self.show_template,
            title=self.user_info_title,
            widgets=widgets,
            appbuilder=self.appbuilder,
        )

    @action('resetmypassword',
            lazy_gettext("Reset my password"),
            "",
            "fa-lock",
            multiple=False)
    @permission_name("RedefinirMinhaSenha")
    def resetmypassword(self, item):
        return redirect(
            url_for(self.appbuilder.sm.resetmypasswordview.__name__ +
                    '.this_form_get'))

    @action('resetpasswords',
            lazy_gettext("Reset Password"),
            "",
            "fa-lock",
            multiple=False)
    @permission_name("RedefinirSenha")
    def resetpasswords(self, item):
        return redirect(
            url_for(self.appbuilder.sm.resetpasswordview.__name__ +
                    '.this_form_get',
                    pk=item.id))

    def pre_update(self, item):
        item.changed_on = datetime.datetime.now()
        item.changed_by_fk = g.user.id

    def pre_add(self, item):
        item.password = generate_password_hash(item.password)