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)
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
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)
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
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)
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')
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)])
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)}))
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'
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, })
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
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(' {}'.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
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)
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_form(**kwargs): """Get subscribe form """ return _frm.Subscribe(_router.request(), **kwargs)
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)
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)
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)
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)
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