def create_update_instance(self, request, instance=None): """**Internal method**. Create/Update an ``instance`` of :attr:`_model`. This method is invoked by both the :meth:`post` and :meth:`update` methods. The data for the update/create operation is obtained from the body of the client request. :param instance: Optional instance of :attr:`_model`. If available, the data is for an ``update`` operation. :return: an http response. """ data, files = yield request.data_and_files() if self.form_factory is not None: form = self.form_factory(request=request, instance=instance, data=data, files=files, manager=self.manager) valid = yield form.is_valid() cm = self.content_manager if valid: response = request.response kw = form.cleaned_data.copy() if instance is None: instance = yield self.create_instance(request, kw) response.status_code = 201 # TODO set the location # response.headers['location'] = else: instance = yield self.update_instance(request, instance, kw) response = yield cm.form_response(form, instance) else: response = yield cm.form_response(form) coroutine_return(response) else: raise Http404
def _anonymous_user(self, request): user = yield request.models.user.filter(username=ANONYMOUS_USER).all() if user: user = user[0] else: user = request.models.user.new(username=ANONYMOUS_USER, can_login=False) coroutine_return(user)
def _inner_form(self, form, request): yield form.is_valid() html = Html(None) for child in self.children: html.append(child(form, request)) for child in form.inputs: html.append(child) content = yield html.render(request) coroutine_return(content)
def login(self, request, user=None): """Login a ``user`` if it is already authenticated, otherwise do nothing.""" cache = request.cache session = cache.session user = user or session.user if user: if session.user_id != user.id: cache.session = yield self._create_session(request, user) coroutine_return(user)
def paginate(self, request, query, parameters): '''Refine ``query`` from input ``parameters`` and perform pagination. Return a pagination info object ''' config = request.app.config columns = self.columns(request, query.model) # search = parameters.pop(config['QUERY_SEARCH_KEY'], None) pretty = parameters.pop('pretty', False) if search: query = query.search(search) # pick up the fields field_key = config['QUERY_FIELD_KEY'] if field_key not in parameters: field_key = '%s[]' % field_key fields = parameters.pop(field_key, None) if fields and not isinstance(fields, list): fields = [fields] if fields: cd = dict(((c.code, c) for c in columns)) columns = [] load_only = set() for field in fields: column = cd.get(field) if column: load_only.update(column.fields) else: column = Column.get(field) columns.append(column) if self.required_fields: load_only.update(self.required_fields) load_only = tuple(load_only) query = query.load_only(*load_only) query = self.safe_filter(query, parameters) # total_size = yield query.count() start = safe_int(parameters.get(config['QUERY_START_KEY'], 0)) length = safe_int(parameters.get(config['QUERY_LENGTH_KEY'])) max_length = config['QUERY_MAX_LENGTH'] if start or length: if not length: end = -1 else: end = start + length data = yield query[start:end] else: length = total_size data = yield query.all() info = self.pag_info(data, start, length, total_size, columns, pretty) coroutine_return(info)
def get_object(self, request, query, parameters): pretty = request.url_data.get('pretty') q = yield self.safe_filter(query, parameters) size = yield q.count() if size == 1: all = yield q.all() if len(all) == 1: o = self.obj_info(all[0], self.columns(request, query.model), pretty) coroutine_return(o) raise Http404
def is_valid(self): '''Asynchronous check if this :class:`Form` is valid. Includes any subforms. It returns a coroutine.''' if not self._check_unwind(False): yield self._unwind() if not bool(self._errors): for fset in self.form_sets.values(): valid = yield fset.is_valid() if not valid: break coroutine_return(not bool(self._errors) if self.is_bound else False)
def handle_update_instance(self, request): '''The ``U`` in CRUD. This method updates an instance of :attr:`_model`. By default it is responds to the ``/<id>`` relative url and ``post`` method. It invokes the :meth:`create_update_instance` method.''' try: instance = yield self.manager.get(**request.urlargs) except Exception: raise Http404 response = yield self.create_update_instance(request, instance) coroutine_return(response)
def handle_update_instance(self, request): """The ``U`` in CRUD. This method updates an instance of :attr:`_model`. By default it is responds to the ``/<id>`` relative url and ``post`` method. It invokes the :meth:`create_update_instance` method.""" try: instance = yield self.manager.get(**request.urlargs) except Exception: raise Http404 response = yield self.create_update_instance(request, instance) coroutine_return(response)
def read_instance(self, request): '''**Internal method**. Read an instance of :attr:`_model`. Return the best possible representation (text, html, json) to the requesting client.''' c = self.content_manager if c: query = self.query(request) content = yield c.object(request, query, request.urlargs) response = yield content.http_response(request) coroutine_return(response) else: raise Http404
def process_response(self, environ, response): """If request.session was modified set a session cookie.""" if response.can_set_cookies(): request = lux.wsgi_request(environ) session = request.cache.session if session is not None: if session.must_save: yield session.save() if session.modified: response.set_cookie(self.session_cookie_name, value=session.id, expires=session.expiry) coroutine_return(response)
def handle_delete_instance(self, request): """The ``D`` in CRUD. This method delete an instance of :attr:`_model`. By default it is responds to the ``/<id>`` relative url and ``delete`` method.""" try: instance = yield self.manager.get(**request.urlargs) except Exception: raise Http404 yield instance.delete() request.response.status_code = 204 coroutine_return(request.response)
def read_instance(self, request): """**Internal method**. Read an instance of :attr:`_model`. Return the best possible representation (text, html, json) to the requesting client.""" c = self.content_manager if c: query = self.query(request) content = yield c.object(request, query, request.urlargs) response = yield content.http_response(request) coroutine_return(response) else: raise Http404
def handle_delete_instance(self, request): '''The ``D`` in CRUD. This method delete an instance of :attr:`_model`. By default it is responds to the ``/<id>`` relative url and ``delete`` method.''' try: instance = yield self.manager.get(**request.urlargs) except Exception: raise Http404 yield instance.delete() request.response.status_code = 204 coroutine_return(request.response)
def _session_from_token(self, request, key): qs = request.models[Session].query().load_related('user') session = yield qs.filter(id=key).all() if session: session = session[0] session.modified = False if session.expired: yield session.delete() session = None else: # HACK!, need to fix stdnet! session.user.session = session.session request.cache.user = session.user else: session = None coroutine_return(session)
def get(self, request): """Handle the ``get`` request on this CRUD url. It retrieve the collection of model instances satisfying the query in the request ``QUERY_STRING``. Subsequently it invokes the :attr:`content_manager` to handle how the query is rendered via the :meth:`.ContentManager.collection` method.""" c = self.content_manager if c: query = self.query(request) params = dict(request.url_data) content = yield c.collection(request, query, params) response = yield content.http_response(request) coroutine_return(response) else: raise Http404
def get(self, request): '''Handle the ``get`` request on this CRUD url. It retrieve the collection of model instances satisfying the query in the request ``QUERY_STRING``. Subsequently it invokes the :attr:`content_manager` to handle how the query is rendered via the :meth:`.ContentManager.collection` method.''' c = self.content_manager if c: query = self.query(request) params = dict(request.url_data) content = yield c.collection(request, query, params) response = yield content.http_response(request) coroutine_return(response) else: raise Http404
def get_def_username(request): # Try to determine the current system user's username to use as a default. try: def_username = getpass.getuser().replace(' ', '').lower() except (ImportError, KeyError): # KeyError will be raised by os.getpwuid() (called by getuser()) # if there is no corresponding entry in the /etc/passwd file # (a very restricted chroot environment, for example). def_username = '' # Determine whether the default username is taken, so we don't display # it as an option. if def_username: user = yield request.app.permissions.get_user(request, username=def_username) if user: def_username = '' coroutine_return(def_username)
def clean(self): '''Process login''' request = self.request permissions = request.app.permissions username = self.cleaned_data['username'] user = yield permissions.get_user(request, username=username) if not user: raise forms.ValidationError(self.error_message) password = self.cleaned_data['password'] try: user = yield permissions.authenticate_and_login( request, user, password=password) except AuthenticationError: raise forms.ValidationError(self.error_message) except LoginError as e: raise forms.ValidationError(str(e)) coroutine_return(user)
def _create_session(self, request, user=None): #Create new session and added it to the environment. old = request.cache.session if isinstance(old, Session): old.expiry = datetime.now() yield old.save() if not user: user = yield self._anonymous_user(request) expiry = datetime.now() + timedelta(seconds=self.session_expiry) pid = os.getpid() sa = os.urandom(self.salt_size) val = to_bytes("%s%s" % (pid, time.time())) + sa + self.secret_key id = sha1(val).hexdigest() #session is a reserved attribute in router, use dict access session = yield request.models[Session].new(id=id, expiry=expiry, user=user) request.cache.user = session.user coroutine_return(session)
def _get_session(self, request): qs = request.url_data session = None if 'access_token' in qs: session = yield self._session_from_token(request, qs['access_token']) if session is None and self.session_cookie_name: cookie_name = self.session_cookie_name cookies = request.response.cookies session_key = cookies.get(cookie_name) session = None if session_key: session = yield self._session_from_token( request, session_key.value) if session is None: session = yield self._create_session(request, request.cache.user) coroutine_return(session)
def _get_session(self, request): qs = request.url_data session = None if 'access_token' in qs: session = yield self._session_from_token(request, qs['access_token']) if session is None and self.session_cookie_name: cookie_name = self.session_cookie_name cookies = request.response.cookies session_key = cookies.get(cookie_name) session = None if session_key: session = yield self._session_from_token(request, session_key.value) if session is None: session = yield self._create_session(request, request.cache.user) coroutine_return(session)
def clean(self): '''Process login''' request = self.request permissions = request.app.permissions username = self.cleaned_data['username'] user = yield permissions.get_user(request, username=username) if not user: raise forms.ValidationError(self.error_message) password = self.cleaned_data['password'] try: user = yield permissions.authenticate_and_login(request, user, password=password) except AuthenticationError: raise forms.ValidationError(self.error_message) except LoginError as e: raise forms.ValidationError(str(e)) coroutine_return(user)
def create_update_instance(self, request, instance=None): '''**Internal method**. Create/Update an ``instance`` of :attr:`_model`. This method is invoked by both the :meth:`post` and :meth:`update` methods. The data for the update/create operation is obtained from the body of the client request. :param instance: Optional instance of :attr:`_model`. If available, the data is for an ``update`` operation. :return: an http response. ''' data, files = yield request.data_and_files() if self.form_factory is not None: form = self.form_factory(request=request, instance=instance, data=data, files=files, manager=self.manager) valid = yield form.is_valid() cm = self.content_manager if valid: response = request.response kw = form.cleaned_data.copy() if instance is None: instance = yield self.create_instance(request, kw) response.status_code = 201 #TODO set the location #response.headers['location'] = else: instance = yield self.update_instance(request, instance, kw) response = yield cm.form_response(form, instance) else: response = yield cm.form_response(form) coroutine_return(response) else: raise Http404
def _get_permissions(self, request, session): roles = yield session.user.roles.query().all() coroutine_return(ModelPermissions(session.user, roles))
def logout(self, request, user=None): session = request.cache.session user = user or session.user if user.is_authenticated(): request.cache.session = yield self._create_session(request) coroutine_return(True)