Closed josejachuf closed 2 years ago
@josejachuf sounds quite strange. I know session data is quite sensitive, but is there any chance for you to share session contents (even in a filtered way)? I suspect something ended up in session but is not pickable..
Hi @gi0baro, this is I what have
current.session: <sdict {'auth': <sdict {'user': <Row {'id': 1, 'created_at': datetime.datetime(2022, 2, 2 2, 15, 59, 4), 'updated_at': datetime.datetime(2022, 2, 22, 15, 59, 4), 'email': '***', 'registration _key': '', 'reset_password_key': '', 'registration_id': '', 'first_name': 'Jose', 'last_name': 'Jachuf', 'avatar': None, 'institucion': 1, 'roles': ['administrador', 'supervisor', 'impersonate']}>, 'last_visit': datetime.datetime( 2022, 3, 3, 18, 31, 20, 263840), 'last_dbcheck': datetime.datetime(2022, 3, 3, 18, 31, 20, 263840), 'expiration': 3 600, 'remember': False}>}>
sdict(current.session): <sdict {'auth': <sdict {'user': <Row {'id': 1, 'created_at': datetime.datetime(202 2, 2, 22, 15, 59, 4), 'updated_at': datetime.datetime(2022, 2, 22, 15, 59, 4), 'email': '***', 'regis tration_key': '', 'reset_password_key': '', 'registration_id': '', 'first_name': 'Jose', 'last_name': 'Jachuf', 'av atar': None, 'institucion': 1, 'roles': ['administrador', 'supervisor', 'impersonate']}>, 'last_visit': datetime.da tetime(2022, 3, 3, 18, 31, 20, 263840), 'last_dbcheck': datetime.datetime(2022, 3, 3, 18, 31, 20, 263840), 'expirat ion': 3600, 'remember': False}>}>
@josejachuf it seems to me the only possible explanation is pickle cannot serialize the Row
object. This will require a bit of investigation from my side, gonna update you once I have news.
Hi @gi0baro
The same app with:
emmett 2.3.1 emmett-rest 1.2.0
works fine
and with:
emmett 2.4.3 emmett-crypto 0.2.2 emmett-rest 1.3.2
failure. I try with encryption_mode modern and legacy and always fail
@josejachuf I can't reproduce your issue.
Can you provide any/all of the following:
The only difference between 2.3 and 2.4 I can think of that might be involved is that rows coming from models (and thus also the one pickled by auth in session) are now a different class (https://github.com/emmett-framework/emmett/blob/master/emmett/orm/models.py#L1087) which defines its own __getstate__
and __setstate__
methods used by pickle
. But I don't get what your user class might contain to break it.
[Python38] It is for an API REST. The login works well, in fact I get the user For the login I use:
user = auth.login(email=email, password=password)
User Model:
class User(AuthUser):
tablename = 'auth_users'
belongs_to({'institucion': 'Institucion'})
avatar = Field.upload(autodelete=True)
@rowattr('nombre_completo')
def _nombre_completo(self, row):
return '%s %s' % (row.last_name, row.first_name)
form_labels = {
'email': 'Correo Electrónico',
'password': 'Contraseña',
'first_name': 'Nombre',
'last_name': 'Apellido',
}
validation = {
'password': {'len': {'gte': 6, 'lte': 256},
'message': 'Ingrese entre 6 y 256 caracteres'
}
}
rest_rw = {
'institucion': True,
'registration_key': True
}
app.pipeline = [
SessionManager.cookies('3253c0e2-f5b7-4a01',
encryption_mode='legacy'
),
db.pipe,
auth.pipe,
]
In this way with legacy I get this error:
Traceback (most recent call last): File "/venv/lib/python3.8/site-packages/emmett/asgi/handlers.py", line 325, in dynamic_handler http = await self.router.dispatch(ctx.request, ctx.response) File "/venv/lib/python3.8/site-packages/emmett/routing/router.py", line 249, in dispatch return await match.dispatch(reqargs, response) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 70, in dispatch await self._parallel_flow(self.flow_open) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 30, in _parallel_flow raise task.exception() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 78, in open_request current.session = self._load_session(current.request) File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 164, in _load_session return self._decrypt_data(cookie_data) File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 148, in _decrypt_data_legacy secure_loads(data, self.key, compression_level=self.compression_level), File "/venv/lib/python3.8/site-packages/emmett/security.py", line 166, in secure_loads return pickle.loads(data) File "/venv/lib/python3.8/site-packages/emmett/orm/models.py", line 1125, in setstate self.dict.update(state["data"]) KeyError: 'data'
whit modern
Traceback (most recent call last): File "/venv/lib/python3.8/site-packages/emmett/asgi/handlers.py", line 325, in dynamic_handler http = await self.router.dispatch(ctx.request, ctx.response) File "/venv/lib/python3.8/site-packages/emmett/routing/router.py", line 249, in dispatch return await match.dispatch(reqargs, response) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 74, in dispatch await self._parallel_flow(self.flow_close) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 30, in _parallel_flow raise task.exception() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 90, in close_request self._pack_session(expiration) File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 61, in _pack_session current.response.cookies[self.cookie_name] = self._session_cookie_data() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 170, in _session_cookie_data return self._encrypt_data() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 141, in _encrypt_data_modern data = pickle.dumps(sdict(current.session)) TypeError: 'NoneType' object is not callable
If I return to emmett 2.3.1 works fine
Jose
@josejachuf I was able to reproduce the bug. It involves belongs
relations on user model. Gonna work on a solution for this and release a patch for 2.4.
@josejachuf this is fixed in 2.4.4
Thanks very much
Hi @gi0baro, now error it is
ERROR in handlers [/venv/lib/python3.8/site-packages/emmett/asgi/hand lers.py:340]: Application exception: Traceback (most recent call last): File "/venv/lib/python3.8/site-packages/emmett/asgi/handlers.py", lin e 325, in dynamic_handler http = await self.router.dispatch(ctx.request, ctx.response) File "/venv/lib/python3.8/site-packages/emmett/routing/router.py", li ne 249, in dispatch return await match.dispatch(reqargs, response) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py ", line 74, in dispatch await self._parallel_flow(self.flow_close) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py ", line 30, in _parallel_flow raise task.exception() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 90, in close_request self._pack_session(expiration) File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 61, in _pack_session current.response.cookies[self.cookie_name] = self._session_cookie_data() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 170 , in _session_cookie_data return self._encrypt_data() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 141 , in _encrypt_data_modern data = pickle.dumps(sdict(current.session)) AttributeError: Can't pickle local object 'attempt_upload_on_insert.
.wrapped' INFO: 127.0.0.1:46254 - "POST /main/api/authsm/login HTTP/1.1" 500 Internal Server Error
@josejachuf it doesn't really make sense to me. Seems it tries to serialize a Model
instance. Is the session still the same, or do you added anything into the model?
@gi0baro During the day I will upload the code that I have. But no, I did not change the model
Hi @gi0baro This already fails with Emmett 2.4 with 2.3 works fine
curl -X POST http://127.0.0.1:8000/main/api/authsm/login -H 'Content-Type: application/json' -d '{"email": "doc@emmettbrown.com","password":"123456"}'
@josejachuf found the bug thanks to the code you posted. Gonna work on it and produce a new patch version in the next few days
@josejachuf this is now fixed in 2.4.5 Thank you for your patience.
Thank you very much, until now everything works fine
Hi @gi0baro
Again, an error occurs with sessions with version 2.4.7
Traceback (most recent call last): File "/venv/lib/python3.8/site-packages/emmett/asgi/handlers.py", line 325, in dynamic_handler http = await self.router.dispatch(ctx.request, ctx.response) File "/venv/lib/python3.8/site-packages/emmett/routing/router.py", line 249, in dispatch return await match.dispatch(reqargs, response) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 74, in dispatch await self._parallel_flow(self.flow_close) File "/venv/lib/python3.8/site-packages/emmett/routing/dispatchers.py", line 30, in _parallel_flow raise task.exception() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 90, in close_request self._pack_session(expiration) File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 61, in _pack_session current.response.cookies[self.cookie_name] = self._session_cookie_data() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 170, in _session_cookie_data return self._encrypt_data() File "/venv/lib/python3.8/site-packages/emmett/sessions.py", line 141, in _encrypt_data_modern data = pickle.dumps(sdict(current.session)) AttributeError: Can't pickle local object 'attempt_upload_on_insert.
.wrapped'
You can try with: https://github.com/emmett-framework/emmett/files/8207695/backend-bug.zip
curl -X POST http://127.0.0.1:8000/main/api/authsm/login -H 'Content-Type: application/json' -d '{"email": "doc@emmettbrown.com](mailto:doc@emmettbrown.com)","password":"123456"}'
Jose
@josejachuf I officially hate this. My bad I didn't add a test for this. Gonna address this properly this time.
No problem. I am in stage of development and I can use the old version
@josejachuf fixed in 2.4.8
This works fine. Thanks!
I get an error here [1]
But all the objects and variables involved contains data, in no case is it None
current.session has data, sdict and pickle existed
emmett 2.4.3 emmett-crypto 0.2.2 emmett-rest 1.3.2
[1] https://github.com/emmett-framework/emmett/blob/8bf5c23c33a0fbdad260789baa6c28e1657bd2e6/emmett/sessions.py#L141