Ejemplo n.º 1
0
    def exec(self):
        del self.args['_pytsite_router_rule_name']
        endpoint = '/' + self.args.pop('http_api_endpoint')
        current_path = router.current_path(False)
        request_method = router.request().method

        # Switch language
        language = router.request().headers.get('Accept-Language')  # type: str
        if language:
            for lng in language.split(','):
                lng = lng.strip()
                if not lng.startswith('q=') and lang.is_defined(language):
                    lang.set_current(language)
                    break
        try:
            events.fire('http_api@pre_request')
            rule = _api.match(router.request().method, endpoint)
            events.fire('http_api@request')

            controller = rule.controller_class()  # type: routing.Controller
            controller.request = self.request
            controller.args.update(self.args)
            controller.args.update(rule.args)
            controller.args['_pytsite_http_api_rule_name'] = rule.name
            controller.args.validate()

            response = controller.exec()
            return response if isinstance(
                response, http.Response) else http.JSONResponse(response)

        except (http.error.Base, errors.ForbidOperation) as e:
            if reg.get('debug'):
                logger.error(e)
            else:
                logger.error('{} {}: {}'.format(request_method, current_path,
                                                e.description))

            if isinstance(e, errors.ForbidOperation):
                e = http.error.Forbidden(e)

            if e.response and isinstance(e.response, http.JSONResponse):
                response = e.response
                response.status_code = e.code
            else:
                # It is important to do `str(e.description)`, because `e.description` might be an exception
                response = http.JSONResponse({'error': str(e.description)},
                                             e.code)

            return response

        except UserWarning as e:
            logger.warn('{} {}: {}'.format(request_method, current_path, e))
            return http.JSONResponse({'warning': str(e)}, 200)

        except Exception as e:
            logger.error('{} {}: {}'.format(request_method, current_path, e),
                         exc_info=e)
            return http.JSONResponse({'error': str(e)}, 500)
Ejemplo n.º 2
0
    def _get_element(self, **kwargs) -> _html.Element:
        """Render widget.
        :param **kwargs:
        """
        # If 'verifier' is here, we need to exchange it to an access token
        if not self._user_id:
            inp_oauth_verifier = _router.request().inp.get('oauth_verifier')
            if inp_oauth_verifier:
                token = self._session.get_access_token(inp_oauth_verifier)
                self._oauth_token = token['oauth_token']
                self._oauth_token_secret = token['oauth_token_secret']
                self._user_id = token['user_id']
                self._screen_name = token['screen_name']

        wrapper = _html.TagLessElement()

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[oauth_token]',
                value=self.oauth_token,
            ).renderable())

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[oauth_token_secret]',
                value=self.oauth_token_secret,
            ).renderable())

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[user_id]',
                value=self.user_id,
            ).renderable())

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[screen_name]',
                value=self.screen_name,
            ).renderable())

        if self.screen_name:
            title = self.screen_name
            href = 'https://twitter.com/' + self._screen_name
        else:
            title = _lang.t('twitter@authorization')
            href = self._session.get_authorization_url(self._callback_uri)

        a = _html.A(title, href=href)
        a.append(_html.I(css='fa fa-twitter'))
        wrapper.append(
            _widget.static.HTML(
                uid=self.uid + '[auth_link]',
                em=a,
            ).renderable())

        return wrapper
Ejemplo n.º 3
0
def restore_account_form(request: http.Request = None, driver_name: str = None, **kwargs) -> form.Form:
    """Get account restoration form
    """
    driver = get_driver(driver_name)

    kwargs.update({
        'name': kwargs.get('name', 'auth-ui-restore-account-' + driver.name),
        'css': kwargs.get('css', '') + ' auth-ui-form auth-ui-restore-account driver-' + driver.name
    })

    return driver.get_restore_account_form(request or router.request(), **kwargs)
Ejemplo n.º 4
0
    def _get_rule(cls, rule_type: str) -> Optional[str]:
        path = router.current_path()

        ref = router.request().referrer
        ref_path = router.url(ref, add_lang_prefix=False,
                              as_list=True)[2] if ref else ''

        if path.startswith(_ADM_BP) or ref_path.startswith(_ADM_BP):
            rule_type = 'admin_' + rule_type

        return 'odm_ui@' + rule_type
Ejemplo n.º 5
0
def sign_up_form(request: http.Request = None, driver_name: str = None, **kwargs) -> form.Form:
    """Get a sign up form
    """
    driver = get_driver(driver_name)

    kwargs.update({
        'action': http_api.url('auth_http_api@sign_up', {'driver': driver.name}),
        'css': kwargs.get('css', '') + ' auth-ui-form auth-ui-sign-up driver-' + driver.name,
        'name': kwargs.get('name', 'auth-ui-sign-up-' + driver.name),
    })

    return driver.get_sign_up_form(request or router.request(), **kwargs)
Ejemplo n.º 6
0
def dispense(uid: str, request: Request = None) -> Form:
    """Dispense a form from the cache
    """
    try:
        if not _FORMS.has(uid):
            raise KeyError(f"Form '{uid}' is not found")

        form = _FORMS.get(uid)
        form.request = request or router.request()
        return form

    except Exception as e:
        logger.error(e)
        raise RuntimeError('Unexpected form exception')
Ejemplo n.º 7
0
    def exec(self):
        """Search taxonomy term titles
        """
        exclude = router.request().inp.get('exclude', [])

        if isinstance(exclude, str):
            exclude = [exclude]

        f = _api.find(self.arg('model'))

        if exclude:
            f.ninc('title', exclude)

        for word in self.arg('query').split(' '):
            f.regex('title', word.strip(), True)

        return http.JSONResponse([e.f_get('title') for e in f.get(10)])
Ejemplo n.º 8
0
def http_api_pre_request():
    access_token = None
    auth_header = router.request().headers.get('Authorization', '').split(' ')

    if len(auth_header) == 2 and auth_header[0].lower() == 'token':
        access_token = auth_header[1].strip()

    if not access_token:
        return

    try:
        # Authorize user by access token
        auth.switch_user(auth.get_user(access_token=access_token))
        auth.prolong_access_token(access_token)

    except (auth.error.InvalidAccessToken, auth.error.UserNotFound,
            auth.error.AuthenticationError) as e:
        raise http.error.Forbidden(
            response=http.JSONResponse({'error': str(e)}))
Ejemplo n.º 9
0
    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', ''),
            ))

        submit_btn = self.get_widget('action_submit')
        submit_btn.value = lang.t('auth_ui_password@reset_password')
        submit_btn.icon = 'fa fa-key'
Ejemplo n.º 10
0
 def render(self, navbar: admin.NavBar, sidebar: admin.SideBar,
            content: Union[str, htmler.Element]):
     return tpl.render(
         'admin_theme_lte@html', {
             'admin_sidebar':
             self._render_sidebar(sidebar),
             'admin_language_nav':
             widget.select.LanguageNav(
                 'admin-language-nav', dropdown=True, bs_version=3),
             'content':
             content,
             'core_name':
             package_info.name('pytsite'),
             'core_url':
             package_info.url('pytsite'),
             'core_version':
             package_info.version('pytsite'),
             'sidebar_collapsed':
             router.request().cookies.get('adminSidebarCollapsed')
             is not None,
         })
Ejemplo n.º 11
0
    def _get_element(self, **kwargs) -> _html.Element:
        """Get HTML element representation of the widget.
        :param **kwargs:
        """
        # 'state' and 'code' typically received after successful Facebook authorization redirect
        inp = _router.request().inp
        state = inp.get('state')
        auth_code = inp.get('code')

        # Try to fetch access token from Facebook
        if not self._access_token and (state and auth_code):
            t_info = _AuthSession(state).get_access_token(auth_code)
            self._access_token = t_info['access_token']
            self._access_token_type = t_info['token_type']

            self._access_token_expires = float(t_info.get('expires_in', 0))
            if self._access_token_expires:
                self._access_token_expires = int(_datetime.now().timestamp() +
                                                 self._access_token_expires)

            me = _Session(self._access_token).me()
            self._user_id = me['id']
            self._screen_name = me['name']

        # Pages
        if self._access_token:
            for acc in _Session(self._access_token).accounts():
                if 'CREATE_CONTENT' in acc['perms']:
                    self._pages.append((acc['id'], acc['name']))

        # Link to user profile or to facebook authorization URL
        if self._user_id and self._screen_name:
            a = _html.A(self._screen_name,
                        href='https://facebook.com/' + self._user_id,
                        target='_blank')
            a.append(_html.I(css='fa fa-facebook-square'))
        else:
            a = _html.A(href=_AuthSession(redirect_uri=self._redirect_url).
                        get_authorization_url(self._scope))
            a.append(
                _html.Img(src=_assetman.url(
                    'facebook@img/facebook-login-button.png')))

        cont = _html.TagLessElement()
        cont.append(
            _widget.static.Text(self.uid + '[auth_url]',
                                label=_lang.t('facebook@user'),
                                text=a.render()).renderable())

        # Page select
        if self.pages:
            cont.append(
                _widget.select.Select(self.uid + '[page_id]',
                                      value=self._page_id,
                                      label=_lang.t('facebook@page'),
                                      items=self.pages,
                                      h_size='col-sm-6').renderable())

        cont.append(
            _widget.input.Hidden(self.uid + '[access_token]',
                                 value=self.access_token).renderable())
        cont.append(
            _widget.input.Hidden(self.uid + '[access_token_type]',
                                 value=self.access_token_type).renderable())
        cont.append(
            _widget.input.Hidden(self.uid + '[access_token_expires]',
                                 value=self.access_token_expires).renderable())
        cont.append(
            _widget.input.Hidden(self.uid + '[user_id]',
                                 value=self.user_id).renderable())
        cont.append(
            _widget.input.Hidden(self.uid + '[screen_name]',
                                 value=self.screen_name).renderable())

        return cont
Ejemplo n.º 12
0
    def _get_element(self, **kwargs) -> _html.Element:
        """Hook
        """
        # If 'verifier' is here, we need to exchange it to an access token
        inp_oauth_token = _router.request().inp.get('oauth_token')
        inp_oauth_verifier = _router.request().inp.get('oauth_verifier')
        if inp_oauth_token and inp_oauth_verifier:
            access_data = TumblrAuthSession(inp_oauth_token).get_access_token(
                self._callback_uri)
            self._oauth_token = access_data['oauth_token']
            self._oauth_token_secret = access_data['oauth_token_secret']
            user_info = TumblrSession(self._oauth_token,
                                      self._oauth_token_secret).user_info()
            self._screen_name = user_info['name']

        if self._oauth_token and self._oauth_token_secret and self._screen_name:
            user_info = TumblrSession(self._oauth_token,
                                      self._oauth_token_secret).user_info()
            self._user_blogs = [(i['name'], i['title'])
                                for i in user_info['blogs']]

        wrapper = _html.TagLessElement()

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[oauth_token]',
                value=self.oauth_token,
            ).renderable())

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[oauth_token_secret]',
                value=self.oauth_token_secret,
            ).renderable())

        wrapper.append(
            _widget.input.Hidden(
                uid=self.uid + '[screen_name]',
                value=self.screen_name,
            ).renderable())

        if self.user_blogs:
            a = _html.A('&nbsp;{}'.format(self.screen_name),
                        href='http://{}.tumblr.com'.format(self.screen_name),
                        target='_blank')
            a.append(_html.I(css='fa fa-fw fa-tumblr'))

            wrapper.append(
                _widget.static.HTML(self.uid + '[user]', em=a).renderable())
            wrapper.append(
                _widget.select.Select(
                    uid=self.uid + '[user_blog]',
                    h_size='col-sm-6',
                    items=self.user_blogs,
                    value=self.user_blog,
                    required=True,
                    label=_lang.t('tumblr@blog')).renderable())
        else:
            auth_s = TumblrAuthSession(
                callback_uri=self._callback_uri).fetch_request_token()
            a = _html.A(_lang.t('tumblr@authorization'),
                        href=auth_s.get_authorization_url())
            a.append(_html.I(css='fa fa-fw fa-tumblr'))
            wrapper.append(
                _widget.static.HTML(self.uid + '[user]', em=a).renderable())

        return wrapper
Ejemplo n.º 13
0
    def odm_ui_m_form_setup_widgets(self, frm: _form.Form):
        """Setup of a modification form.
        """
        if frm.current_step == 1:
            frm.add_widget(_widget.select.Checkbox(
                weight=10,
                uid='enabled',
                label=self.t('enabled'),
                value=self.enabled,
            ))

            frm.add_widget(_file_ui.widget.ImagesUpload(
                weight=20,
                uid='logo',
                label=self.t('logo'),
                value=self.logo,
                max_files=1,
                show_numbers=False,
                dnd=False,
            ))

            frm.add_widget(_widget.input.Text(
                weight=30,
                uid='description',
                label=self.t('description'),
                value=self.description,
            ))

            frm.add_widget(_content.widget.ModelSelect(
                weight=40,
                uid='content_model',
                label=self.t('content_model'),
                value=self.content_model,
                h_size='col-sm-4',
                required=True,
            ))

            frm.add_widget(_section.widget.SectionSelect(
                weight=50,
                uid='content_section',
                label=self.t('content_section'),
                value=self.content_section,
                h_size='col-sm-4',
                required=True,
            ))

            frm.add_widget(_content.widget.StatusSelect(
                weight=60,
                uid='content_status',
                label=self.t('content_status'),
                value=self.content_status,
                h_size='col-sm-4',
                required=True,
            ))

            frm.add_widget(_auth_ui.widget.UserSelect(
                weight=70,
                uid='content_author',
                label=self.t('content_author'),
                value=self.content_author if not self.is_new else _auth.get_current_user(),
                h_size='col-sm-4',
                required=True,
            ))

            frm.add_widget(_content_import_widget.DriverSelect(
                weight=80,
                uid='driver',
                label=self.t('driver'),
                value=self.driver,
                h_size='col-sm-4',
                required=True,
            ))

            frm.add_widget(_widget.input.Tokens(
                weight=90,
                uid='add_tags',
                label=self.t('additional_tags'),
                value=self.add_tags,
            ))

            frm.add_widget(_widget.select.DateTime(
                weight=100,
                uid='paused_till',
                label=self.t('paused_till'),
                value=self.paused_till,
                h_size='col-sm-5 col-md-4 col-lg-3',
                hidden=self.is_new,
            ))

            frm.add_widget(_widget.input.Integer(
                weight=110,
                uid='errors',
                label=self.t('errors'),
                value=self.errors,
                h_size='col-sm-1',
                hidden=self.is_new or not self.errors,
            ))

            frm.add_widget(_widget.static.Text(
                weight=120,
                uid='content_language',
                label=self.t('content_language'),
                value=self.content_language,
                text=_lang.lang_title(self.content_language),
                h_size='col-sm-4',
                required=True,
            ))

        if frm.current_step == 2:
            driver = _api.get_driver(_router.request().inp.get('driver'))
            settings_widget = driver.get_settings_widget(self.driver_opts)
            frm.add_widget(settings_widget)
Ejemplo n.º 14
0
    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'
Ejemplo n.º 15
0
    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'
Ejemplo n.º 16
0
def get_form(**kwargs):
    """Get subscribe form
    """
    return _frm.Subscribe(_router.request(), **kwargs)
Ejemplo n.º 17
0
def get_m_form(model: str, eid: str = None, **kwargs) -> _forms.Modify:
    """Get entity modification form
    """
    return _forms.Modify(router.request(), model=model, eid=eid, **kwargs)
Ejemplo n.º 18
0
def role_form(request: http.Request = None, role_uid: str = None) -> form.Form:
    """Get role edit form
    """
    form_cls = util.get_module_attr(reg.get('auth_ui.role_form_class', 'plugins.auth_ui._frm.Role'))

    return form_cls(request or router.request(), role_uid=role_uid)
Ejemplo n.º 19
0
def user_form(request: http.Request = None, user_uid: str = None) -> form.Form:
    """Get user edit form
    """
    form_cls = util.get_module_attr(reg.get('auth_ui.user_form_class', 'plugins.auth_ui._frm.User'))

    return form_cls(request or router.request(), user_uid=user_uid)
Ejemplo n.º 20
0
def get_d_form(model: str, eids: Iterable, **kwargs) -> form.Form:
    """Get entities delete form
    """
    return _forms.Delete(router.request(), model=model, eids=eids, **kwargs)
Ejemplo n.º 21
0
    def sign_up(self, data: dict) -> _auth.model.AbstractUser:
        # Searching for token in input data
        token = data.get('token')
        if not token:
            for k, v in data.items():
                if k.endswith('token'):
                    token = v
                    break

        if not token:
            raise ValueError('No uLogin token received')

        # Getting user's data from uLogin
        response = _urlopen(
            'http://ulogin.ru/token.php?token={}&host={}'.format(
                token,
                _router.request().host))
        if response.status != 200:
            raise _auth.error.AuthenticationError(
                "Bad response status code from uLogin: {}.".format(
                    response.status))
        ulogin_data = _json.loads(response.read().decode('utf-8'))
        if 'error' in ulogin_data:
            raise _auth.error.AuthenticationError(
                "Bad response from uLogin: '******'.".format(ulogin_data['error']))
        if 'email' not in ulogin_data or ulogin_data['verified_email'] != '1':
            raise _auth.error.AuthenticationError(
                "Email '{}' is not verified by uLogin.".format(
                    ulogin_data['email']))

        email = ulogin_data['email']

        try:
            user = _auth.get_user(email)
            is_new_user = False

        except _auth.error.UserNotFound:
            # User is not exists and its creation is not allowed
            if not _auth.is_sign_up_enabled():
                raise _auth.error.AuthenticationError(
                    _lang.t('auth_ui_ulogin@signup_is_disabled'))
            else:
                # New users can be created only by system user
                _auth.switch_user_to_system()

                # Create new user
                user = _auth.create_user(email)
                is_new_user = True

        # As soon as user created or loaded, set it as current
        _auth.switch_user(user)

        # Picture
        if is_new_user:
            current_pic = user.picture
            picture_url = ulogin_data.get('photo_big')
            if not picture_url:
                picture_url = ulogin_data.get('photo')

            # Replace existing picture with provided by uLogin
            if picture_url:
                user.picture = _file.create(picture_url)
                current_pic.delete()

        # Name
        if not user.first_name:
            user.first_name = ulogin_data.get('first_name')
        if not user.last_name:
            user.last_name = ulogin_data.get('last_name')

        # Alter nickname
        if is_new_user:
            user.nickname = user.first_last_name

        # Gender
        if user.gender not in ('m', 'f') and 'sex' in ulogin_data:
            user.gender = 'f' if int(ulogin_data['sex']) == 1 else 'm'

        # Birth date
        if 'bdate' in ulogin_data:
            try:
                b_date = _strptime(ulogin_data['bdate'], '%d.%m.%Y')
                user.birth_date = _datetime(*b_date[0:5])
            except ValueError:
                # Yes, sometimes uLogin provides strange data here :(
                pass

        # Link to profile
        if 'profile' in ulogin_data and ulogin_data['profile']:
            user.urls = user.urls + (ulogin_data['profile'], )

        # Options
        options = dict(user.options)
        options['ulogin'] = ulogin_data
        user.options = options

        user.save()

        return user