Exemple #1
0
    def __init__(self, uid: str, **kwargs):
        rows_url = http_api.url('auth_admin@browser_rows', {'e_type': 'role'})

        data_fields = [
            ('name', 'auth_admin@name', True),
            ('description', 'auth_admin@description', False),
            ('permissions', 'auth_admin@permissions', False),
            ('_actions', 'auth_admin@actions', False),
        ]

        super().__init__(uid,
                         rows_url=rows_url,
                         data_fields=data_fields,
                         checkbox=False,
                         **kwargs)

        add_btn_url = router.rule_url(
            'auth_admin@form_role_modify', {
                'uid': '0',
                '__redirect': router.rule_url('auth_admin@browse_roles')
            })
        add_btn = htmler.A(href=add_btn_url, css='btn btn-default btn-light')
        add_btn.append_child(htmler.I(css='fa fa-plus'))
        self.toolbar.append_child(add_btn)

        self._css += ' widget-auth-admin-browser'
Exemple #2
0
    def __init__(self, uid: str, **kwargs):
        rows_url = http_api.url('auth_admin@browser_rows', {'e_type': 'user'})

        data_fields = [
            ('login', 'auth_admin@login', True),
            ('first_last_name', 'auth_admin@full_name', True),
            ('roles', 'auth_admin@roles', False),
            ('status', 'auth_admin@status', True),
            ('is_public', 'auth_admin@is_public', True),
            ('is_online', 'auth_admin@is_online', True),
            ('created', 'auth_admin@created', True),
            ('last_activity', 'auth_admin@last_activity', True),
            ('_actions', 'auth_admin@actions', False),
        ]

        super().__init__(uid,
                         rows_url=rows_url,
                         data_fields=data_fields,
                         checkbox=False,
                         **kwargs)

        add_btn_url = router.rule_url(
            'auth_admin@form_user_modify', {
                'uid': '0',
                '__redirect': router.rule_url('auth_admin@browse_users')
            })
        add_btn = htmler.A(href=add_btn_url, css='btn btn-default btn-light')
        add_btn.append_child(htmler.I(css='fa fa-plus'))
        self.toolbar.append_child(add_btn)

        self._css += ' widget-auth-admin-browser'
Exemple #3
0
    def render(self) -> str:
        # 'Create' toolbar button
        if self._model_class.odm_ui_creation_allowed(
        ) and odm_auth.check_model_permissions(self._model, PERM_CREATE):
            create_form_url = router.rule_url(
                self._m_form_rule, {
                    'model': self._model,
                    'eid': 0,
                    '__redirect': router.current_url(),
                })
            title = lang.t('odm_ui@create')
            btn = htmler.A(href=create_form_url,
                           css='btn btn-default btn-light add-button',
                           title=title)
            btn.append_child(htmler.I(css='fa fas fa-fw fa-plus'))
            self._widget.toolbar.append_child(btn)
            self._widget.toolbar.append_child(htmler.Span(' '))

        # 'Delete' toolbar button
        if self._model_class.odm_ui_deletion_allowed():
            delete_form_url = router.rule_url(self._d_form_rule,
                                              {'model': self._model})
            title = lang.t('odm_ui@delete_selected')
            btn = htmler.A(
                href=delete_form_url,
                css='hidden btn btn-danger mass-action-button sr-only',
                title=title)
            btn.append_child(htmler.I(css='fa fas fa-fw fa-remove fa-times'))
            self._widget.toolbar.append_child(btn)
            self._widget.toolbar.append_child(htmler.Span(' '))

        # Additional toolbar buttons
        for btn_data in self._model_class.odm_ui_browser_mass_action_buttons():
            ep = btn_data.get('ep')
            url = router.rule_url(ep) if ep else '#'
            css = 'btn btn-{} mass-action-button'.format(
                btn_data.get('color', 'default btn-light'))
            icon = 'fa fas fa-fw fa-' + btn_data.get('icon', 'question')
            button = htmler.A(href=url, css=css, title=btn_data.get('title'))
            if icon:
                button.append_child(htmler.I(css=icon))
            self._widget.toolbar.append_child(button)
            self._widget.toolbar.append_child(htmler.Span(' '))

        frm = htmler.Form(self._widget.render(),
                          action='#',
                          method='post',
                          css='table-responsive odm-ui-browser')

        return frm.render()
Exemple #4
0
    def odm_ui_browser_entity_actions(self, browser) -> List[Dict]:
        """Get actions buttons data for single data row.
        """
        r = []

        if self.odm_ui_modification_allowed(
        ) and self.odm_auth_check_entity_permissions(PERM_MODIFY):
            r.append({
                'url':
                router.rule_url(
                    browser.m_form_rule, {
                        'model':
                        self.model,
                        'eid':
                        str(self.id),
                        '__redirect':
                        router.rule_url(browser.browse_rule,
                                        {'model': self.model}),
                    }),
                'title':
                lang.t('odm_ui@modify'),
                'icon':
                'fa fas fa-fw fa-fw fa-edit',
            })

        if self.odm_ui_deletion_allowed(
        ) and self.odm_auth_check_entity_permissions(PERM_DELETE):
            r.append({
                'url':
                router.rule_url(
                    browser.d_form_rule, {
                        'model':
                        self.model,
                        'ids':
                        str(self.id),
                        '__redirect':
                        router.rule_url(browser.browse_rule,
                                        {'model': self.model}),
                    }),
                'title':
                lang.t('odm_ui@delete'),
                'icon':
                'fa fas fa-fw fa-fw fa-remove fa-times',
                'color':
                'danger',
            })

        return r
Exemple #5
0
def on_auth_sign_up(user: auth.AbstractUser):
    # Set session notification
    router.session().add_success_message(
        lang.t('auth_ui@registration_form_success'))

    # Send a confirmation email to the user
    if auth.is_sign_up_confirmation_required():
        msg = tpl.render(
            'auth_ui@mail/{}/sign-up'.format(lang.get_current()), {
                'user':
                user,
                'confirm_url':
                router.rule_url('auth_ui@sign_up_confirm',
                                {'code': user.confirmation_hash})
                if not user.is_confirmed else None
            })
        mail.Message(user.login, lang.t('auth_ui@confirm_registration'),
                     msg).send()

    # Send a notification emails to admins
    if auth.is_sign_up_admins_notification_enabled():
        for admin in auth.get_admin_users():
            msg = tpl.render(
                'auth_ui@mail/{}/sign-up-admin-notify'.format(
                    lang.get_current()), {
                        'admin': admin,
                        'user': user,
                    })
            mail.Message(admin.login,
                         lang.t('auth_ui@registration_admin_notify'),
                         msg).send()
    def _on_submit(self):
        try:
            user = auth.get_user(self.val('login'))
            if user.status != auth.USER_STATUS_ACTIVE:
                return

            token = util.random_password(64, True)
            _RESET_TOKENS_POOL.put(token, user.login, _RESET_TOKEN_TTL)
            reset_url = router.rule_url('auth_ui_password@reset',
                                        {'token': token})
            msg_body = tpl.render(
                'auth_ui_password@mail/{}/reset-password'.format(
                    lang.get_current()), {
                        'user': user,
                        'reset_url': reset_url
                    })
            mail.Message(
                user.login,
                lang.t('auth_ui_password@reset_password_mail_subject'),
                msg_body).send()

            router.session().add_info_message(
                lang.t('auth_ui_password@check_email_for_instructions'))

        except auth.error.UserNotFound:
            pass
Exemple #7
0
    def odm_ui_d_form_url(self, args: dict = None, **kwargs) -> str:
        if args is None:
            args = {}

        args.update({'model': self.model, 'eids': str(self.id)})

        return router.rule_url(self.odm_ui_d_form_rule(), args, **kwargs)
Exemple #8
0
def sign_up_url(driver_name: str = None, add_query: dict = None, add_fragment: str = '') -> str:
    """Get sign up URL
    """
    return router.rule_url('auth_ui@sign_up', {
        'driver': get_driver(driver_name).name,
        '__redirect': router.current_url(query=add_query, fragment=add_fragment)
    })
Exemple #9
0
    def odm_ui_browse_url(self, args: dict = None, **kwargs):
        """Get browse URL
        """
        if args is None:
            args = {}

        args.update({'model': self.model})

        return router.rule_url(self.odm_ui_browse_rule(), args, **kwargs)
    def _get_role_row(role: auth.AbstractRole) -> dict:

        perms = []
        for perm_name in role.permissions:
            # If permission was renamed or deleted (sometimes it happens), juts ignore it
            if not permissions.is_permission_defined(perm_name):
                continue

            perm = permissions.get_permission(perm_name)
            css = 'label label-default permission-' + perm[0]
            if perm[0] == 'admin':
                css += ' label-danger'
            perms.append(str(htmler.Span(lang.t(perm[1]), css=css)))

        role_desc = role.description
        try:
            role_desc = lang.t(role_desc)
        except lang.error.Error:
            pass

        m_url = router.rule_url(
            'auth_admin@form_role_modify', {
                'uid': role.uid,
                '__redirect': router.rule_url('auth_admin@browse_roles')
            })
        actions = '<a href="{}" class="btn btn-default btn-light btn-sm">' \
                  '<i class="fa fas fa-edit"></i></a>'.format(m_url)
        d_url = router.rule_url(
            'auth_admin@form_role_delete', {
                'eids': role.uid,
                '__redirect': router.rule_url('auth_admin@browse_roles')
            })
        if role.name not in ('dev', 'admin', 'user', 'anonymous'):
            actions += '&nbsp;<a href="{}" class="btn btn-danger btn-sm">' \
                       '<i class="fa fas fa-remove fa-times"></i></a>'.format(d_url)

        return {
            'name': role.name,
            'description': role_desc,
            'permissions': ' '.join(perms),
            '_actions': '<div class="entity-actions">{}</div>'.format(actions),
        }
Exemple #11
0
    def content_breadcrumb(self, breadcrumb: widget.select.Breadcrumb):
        """Hook
        """
        if self.has_field('section') and self.section:
            breadcrumb.append_item(self.section.title, router.rule_url('content@index', {
                'model': self.model,
                'term_field': 'section',
                'term_alias': self.section.alias,
            }))

        if self.has_field('title'):
            breadcrumb.append_item(self.title)
Exemple #12
0
    def before(self) -> Optional[http.RedirectResponse]:
        if not auth.get_current_user().is_anonymous:
            return

        # Redirecting to the authorization endpoint
        inp = self.request.inp.copy()
        inp.update({
            'driver': _api.get_driver().name,
            '__redirect': util.escape_html(router.current_url(True)),
        })

        return self.redirect(router.rule_url('auth_ui@sign_in', inp))
Exemple #13
0
def sign_in_url(driver_name: str = None, redirect: str = 'CURRENT_URL', add_query: dict = None,
                add_fragment: str = '') -> str:
    """Get sign in URL
    """
    rule_args = {
        'driver': get_driver(driver_name).name,
    }

    if redirect:
        rule_args['__redirect'] = redirect.replace('CURRENT_URL', router.current_url())

    return router.rule_url('auth_ui@sign_in', rule_args, query=add_query, fragment=add_fragment)
Exemple #14
0
    def odm_ui_m_form_url(self, args: dict = None, **kwargs):
        """Get modify form URL
        """
        if args is None:
            args = {}

        args.setdefault('__redirect', 'ENTITY_VIEW')

        args.update({
            'model': self.model,
            'eid': '0' if self.is_new else str(self.id),
        })

        return router.rule_url(self.odm_ui_m_form_rule(), args, **kwargs)
Exemple #15
0
    def get_field(self, field_name: str, **kwargs) -> _Any:
        # File download URL
        if field_name == 'url':
            return _router.rule_url('file@download', {'uid': self.uid})

        elif field_name == 'thumb_url':
            ext = self.ext.replace('.', '').lower()
            if ext in _EXT_THUMB:
                ext = _EXT_THUMB[ext]

            return _assetman.url(
                'file@thumbs/{}.svg'.format(ext if ext in _THUMBS else 'file'))

        raise NotImplementedError()
Exemple #16
0
    def odm_ui_view_url(self, args: dict = None, **kwargs) -> str:
        if self.is_new:
            raise RuntimeError(
                "Cannot generate view URL for non-saved entity of model '{}'".
                format(self.model))

        if args is None:
            args = {}

        args.update({
            'model': self.model,
            'eid': str(self.id),
        })

        return router.rule_url(self.odm_ui_view_rule(), args, **kwargs)
Exemple #17
0
 def get_authorization_url(self,
                           scope='public_profile,email,user_friends'
                           ) -> str:
     """Get authorization URL which used to point user for authorization.
     """
     return _router.url('https://www.facebook.com/dialog/oauth',
                        query={
                            'client_id':
                            self._app_id,
                            'state':
                            self._state,
                            'redirect_uri':
                            _router.rule_url('facebook@authorize'),
                            'scope':
                            scope,
                        })
Exemple #18
0
    def _on_setup_form(self):
        """Hook
        """
        super()._on_setup_form()

        model = self.attr('model')
        if not model:
            raise ValueError('Model is not specified')

        eids = self.attr('eids', self.attr('ids', []))
        if isinstance(eids, str):
            self.set_attr('eids', eids.split(','))

        if not self.redirect:
            from ._api import get_model_class
            self.redirect = router.rule_url(
                get_model_class(model).odm_ui_browse_rule(), {'model': model})

        self.css += ' odm-ui-mass-action-form'
Exemple #19
0
def _set_webhook(bot_token: str, bot_uid: str, max_connections: int = 40, allowed_updates: list = None) -> bool:
    """Specify an URL and receive incoming updates via an outgoing webhook

    https://core.telegram.org/bots/api#setwebhook
    """
    hook_url = router.rule_url('telegram@bot_hook', {'bot_uid': bot_uid}, scheme='https')
    if _get_webhook_info(bot_token)['url'] != hook_url:
        try:
            return request(bot_token, 'setWebhook', {
                'url': hook_url,
                'max_connections': max_connections,
                'allowed_updates': allowed_updates or [],
            })

        except _error.ApiRequestError as e:
            if e.response.status_code == 404:
                raise _error.BotNotFound(bot_token)

            raise e
    def _on_f_get(self, field_name: str, value, **kwargs):
        """Hook.
        """
        if field_name == 'url':
            enlarge = kwargs.get('enlarge', True)

            try:
                width = abs(int(kwargs.get('width', 0)))
                if width:
                    if not enlarge and width > self.f_get('width'):
                        width = self.f_get(self.f_get('width'))
                    width = _api.align_image_side(
                        width, _api.get_image_resize_limit_width())

                height = abs(int(kwargs.get('height', 0)))
                if height:
                    if not enlarge and height > self.f_get('height'):
                        height = self.f_get(self.f_get('height'))
                    height = _api.align_image_side(
                        height, _api.get_image_resize_limit_height())

            except ValueError:
                raise ValueError(
                    'Width and height should be positive integers')

            uid = str(self.id)
            extension = _path.splitext(self.f_get('path'))[1]
            return _router.rule_url('file_storage_odm@image', {
                'width': width,
                'height': height,
                'p1': uid[:2],
                'p2': uid[2:4],
                'filename': '{}{}'.format(uid, extension)
            },
                                    add_lang_prefix=False)

        elif field_name == 'thumb_url':
            return self.f_get('url',
                              width=kwargs.get('thumb_width', 500),
                              height=kwargs.get('thumb_height', 500))

        else:
            return super()._on_f_get(field_name, value, **kwargs)
Exemple #21
0
    def get_access_token(self, auth_code: str) -> dict:
        """Get access token from Facebook.
        """
        url = _router.url(_API_REQUEST_URL + 'oauth/access_token',
                          query={
                              'client_id':
                              self._app_id,
                              'client_secret':
                              self._app_secret,
                              'redirect_uri':
                              _router.rule_url('facebook@authorize'),
                              'code':
                              auth_code,
                          })

        r = _requests.get(url).json()
        if 'error' in r:
            raise _error.AuthSessionError(r['error']['message'])

        return r
Exemple #22
0
    def __init__(self, uid: str, **kwargs):
        """Init.
        """
        if 'default' not in kwargs:
            kwargs['default'] = []

        super().__init__(uid, **kwargs)

        self._model = kwargs.get('model')
        if not self._model:
            raise ValueError('Model is not specified')

        self._remote_source = router.rule_url('taxonomy@search_terms', {
            'model': self._model,
            'query': '__QUERY'
        })

        self._data.update({
            'local_source': self._local_source,
            'remote_source': self._remote_source,
        })
Exemple #23
0
    def _on_submit(self):
        user_uid = self.attr('user_uid')
        c_user = auth.get_current_user()

        if user_uid == '0':
            user = auth.create_user(self.val('login'), self.val('password'))
        else:
            user = auth.get_user(uid=user_uid)

        for k, v in self.values.items():
            if not user.has_field(k):
                continue

            if k in ('login', 'status', 'roles') and not c_user.is_admin:
                continue

            user.set_field(k, v)

        user.save()

        if not self.redirect:
            self.redirect = router.rule_url('auth_ui@user_profile_view', {'nickname': user.nickname})
    def _on_submit(self):
        """Hook
        """
        try:
            token = self.attr('token')
            user = auth.get_user(_RESET_TOKENS_POOL.get(token))

            auth.switch_user_to_system()
            user.password = self.val('password')
            user.save()
            auth.restore_user()

            _RESET_TOKENS_POOL.rm(token)

            router.session().add_success_message(
                lang.t('auth_ui_password@reset_password_success'))

            self.redirect = router.rule_url('auth_ui@sign_in',
                                            {'driver': 'password'})

        except auth.error.UserNotFound:
            raise RuntimeError('Invalid token')
Exemple #25
0
    def _on_submit(self):
        setting_uid = self.attr('setting_uid')

        # Extract all values who's name starts with 'setting_'
        setting_value = reg.get(setting_uid, {})
        for k, v in self.values.items():
            if k.startswith('setting_'):
                k = _re.sub('^setting_', '', k)

                if isinstance(v, (list, tuple)):
                    v = util.cleanup_list(v)

                if isinstance(v, dict):
                    v = util.cleanup_dict(v)

                setting_value[k] = v

        # Update settings
        reg.put(setting_uid, setting_value)

        # Notify user
        router.session().add_success_message(lang.t('settings@settings_has_been_saved'))

        self.redirect = router.rule_url('settings@get_form', {'uid': setting_uid})
Exemple #26
0
    def _on_setup_widgets(self):
        """Hook
        """
        setting_uid = self.attr('setting_uid')

        events.fire('[email protected]_widgets', frm=self)
        events.fire('[email protected]_widgets.' + setting_uid, frm=self)

        # Fill form widgets with values
        for k, v in reg.get(setting_uid, {}).items():
            try:
                self.get_widget('setting_' + k).value = v
            except form.WidgetNotExistError:
                pass

        # "Cancel" button
        self.add_widget(widget.button.Link(
            uid='action_cancel_' + str(self.current_step),
            weight=100,
            value=lang.t('settings@cancel'),
            icon='fa fas fa-fw fa-ban',
            href=router.rule_url('admin@dashboard'),
            form_area='footer',
        ))
Exemple #27
0
def sign_out_url(redirect: str = 'CURRENT_URL') -> str:
    """Get sign out URL
    """
    rule_args = {'__redirect': redirect.replace('CURRENT_URL', router.current_url())} if redirect else {}

    return router.rule_url('auth_ui@sign_out', rule_args)
    def _on_setup_widgets(self):
        """Hook
        """
        self.add_widget(
            widget.input.Email(
                uid='login',
                weight=10,
                placeholder=lang.t('auth_ui_password@email'),
                prepend='<i class="fa fa-fw fa-envelope"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
                value=router.request().inp.get('login', ''),
            ))

        self.add_widget(
            widget.input.Password(
                uid='password',
                weight=20,
                placeholder=lang.t('auth_ui_password@password'),
                prepend='<i class="fa fa-fw fa-lock"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
            ))

        self.add_widget(
            widget.input.Password(
                uid='password_confirm',
                weight=30,
                placeholder=lang.t('auth_ui_password@password_confirm'),
                prepend='<i class="fa fa-fw fa-lock"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
            ))

        self.add_widget(
            widget.input.Text(
                uid='first_name',
                weight=40,
                placeholder=lang.t('auth_ui_password@first_name'),
                prepend='<i class="fa fa-fw fa-address-book"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
            ))

        self.add_widget(
            widget.input.Text(
                uid='last_name',
                weight=50,
                placeholder=lang.t('auth_ui_password@last_name'),
                prepend='<i class="fa fa-fw fa-address-book"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
            ))

        sign_in_url = router.rule_url('auth_ui@sign_in',
                                      {'driver': 'password'})
        self.add_widget(
            widget.static.Text(
                uid='sign_in_link',
                weight=60,
                text=lang.t('auth_ui_password@sign_up_form_propose',
                            {'url': sign_in_url}),
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                css='text-center',
            ))

        submit_btn = self.get_widget('action_submit')
        submit_btn.value = lang.t('auth_ui_password@sign_up')
        submit_btn.icon = 'fa fa-user-plus'
    def _on_setup_widgets(self):
        """Hook
        """

        self.add_widget(
            widget.input.Email(
                uid='login',
                weight=10,
                placeholder=lang.t('auth_ui_password@email'),
                prepend='<i class="fa fa-fw fa-envelope"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
                value=router.request().inp.get('login', ''),
            ))

        self.add_widget(
            widget.input.Password(
                uid='password',
                weight=20,
                placeholder=lang.t('auth_ui_password@password'),
                prepend='<i class="fa fa-fw fa-lock"></i>',
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                h_size_label=True,
                required=True,
            ))

        if auth.is_sign_up_enabled():
            sign_up_url = router.rule_url('auth_ui@sign_up',
                                          {'driver': 'password'})
            self.add_widget(
                widget.static.Text(
                    uid='sign_up_link',
                    weight=30,
                    text=lang.t('auth_ui_password@sign_in_form_propose',
                                {'url': sign_up_url}),
                    h_size='col col-sm-6'
                    if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                    h_size_row_css='justify-content-center'
                    if _BS_VER == 4 else '',
                    css='text-center',
                ))

        reset_pw_url = router.rule_url('auth_ui@restore_account',
                                       {'driver': 'password'})
        self.add_widget(
            widget.static.Text(
                uid='reset_pw_link',
                weight=40,
                text=lang.t('auth_ui_password@reset_password_propose',
                            {'url': reset_pw_url}),
                h_size='col col-sm-6'
                if _BS_VER == 4 else 'col-sm-6 col-sm-offset-3',
                h_size_row_css='justify-content-center'
                if _BS_VER == 4 else '',
                css='text-center',
            ))

        submit_btn = self.get_widget('action_submit')
        submit_btn.value = lang.t('auth_ui_password@sign_in')
        submit_btn.icon = 'fa fa-sign-in'
    def _get_user_row(user: auth.AbstractUser) -> dict:
        yes = lang.t('auth_admin@word_yes')

        roles = ''
        for role in sorted(user.roles, key=lambda rl: rl.name):
            css = 'label label-default'
            if role.name in ('admin', 'dev'):
                css += ' label-danger'
            role_desc = role.description
            try:
                role_desc = lang.t(role_desc)
            except lang.error.Error:
                pass
            roles += str(htmler.Span(role_desc, css=css)) + ' '

        status = user.status
        if status == auth.USER_STATUS_ACTIVE:
            status_css = 'info'
        elif status == auth.USER_STATUS_WAITING:
            status_css = 'warning'
        else:
            status_css = 'default'
        status_word = lang.t('auth@status_' + user.status)
        status = '<span class="label label-{}">{}</span>'.format(
            status_css, status_word)

        is_online = '<span class="label label-success">{}</span>'.format(yes) \
            if (user.last_activity and ((datetime.now() - user.last_activity).seconds < 180)) else ''

        m_url = router.rule_url(
            'auth_admin@form_user_modify', {
                'uid': user.uid,
                '__redirect': router.rule_url('auth_admin@browse_users')
            })
        actions = '<a href="{}" class="btn btn-default btn-light btn-sm">' \
                  '<i class="fa fas fa-edit"></i></a>'.format(m_url)
        if user != auth.get_current_user():
            d_url = router.rule_url(
                'auth_admin@form_user_delete', {
                    'eids': user.uid,
                    '__redirect': router.rule_url('auth_admin@browse_users')
                })
            actions += '&nbsp;<a href="{}" class="btn btn-danger btn-sm">' \
                       '<i class="fa fas fa-remove fa-times"></i></a>'.format(d_url)

        return {
            'login':
            user.login,
            'first_last_name':
            user.first_last_name,
            'roles':
            roles,
            'status':
            status,
            'is_public':
            '<span class="label label-info">{}</span>'.format(yes)
            if user.is_public else '',
            'is_online':
            is_online,
            'created':
            lang.pretty_date_time(user.created),
            'last_activity':
            lang.pretty_date_time(user.last_activity)
            if user.last_activity else '',
            '_actions':
            '<div class="entity-actions">{}</div>'.format(actions),
        }