ZeroFramePy and multiuser does not work correctly
krzotr opened this issue · 6 comments
Hi,
When i try to use ZeroFramePy
with multiuser
I got error
How to reproduce?
Preparation - Debug:
- put
websocket.enableTrace(True)
in_get_websocket
- put
print(message)
in_on_request
- Go Zeronet web page and logout your current user
- Refresh Zeronet web page
- Run ZeroFramePy command e.g.
siteInfo
- I got error
{'error': 'No user found'}
error from callback <bound method ZeroFrame._on_request of <__main__.ZeroApp object at 0x7f621f985350>>: 'cmd'
File "/home/ko/dev/ZeroFramePy/venv/lib64/python3.7/site-packages/websocket/_app.py", line 343, in _callback
callback(*args)
File "/home/ko/dev/ZeroFramePy/zeroframe_ws_client/__init__.py", line 184, in _on_request
cmd = message['cmd']
send: b'\x88\x82\x860l\x9a\x85\xd8'
Traceback (most recent call last):
File "/home/ko/dev/ZeroFramePy/test.py", line 35, in <module>
main()
File "/home/ko/dev/ZeroFramePy/test.py", line 31, in main
print(result.result())
asyncio.base_futures.InvalidStateError: Result is not set.
- Go to Zeronet web and login
- Repeat step 3
- Everything is OK, I got response from server
{'auth_key': '', '...')
How to resolve?
I think we have to login first to get full access to the API via WebSocket
I will also check this tomorrow.
This is known issue for both ZeroFramePy and ZeroFrameJS:
If ZeroNet instance is using
Multiuser
plugin, you need to specify a master address of the account you want to use. Account must already exist on the instance.If you want to create a new account, you also need to specify a master seed of it. Note that this feature is unsafe on the untrusted proxy. Also, it is currently not implemented yet.
Problem is that ZeroFramePy only sends master address as a cookie. But to actually use it, it's private key must already exist on ZeroNet instance. That's why it works when user is logged in (private key is saved) and not when it is logged out.
To support "remote login", you would need to also send private key to instance. ZeroFramePy already supports parameter (multiuser_master_seed
) for that, but logging in is currently not implemented.
I'm also working to figure out how to implement this. Problem is that Multiuser
plugin (userLoginForm
) heavily relies on getting private key input from HTML and JS forms, which are obiusly not supported in this client. Some solution to this would be to modify Multiuser
plugin to also add additional command (userLogin
) which directly gets private key and logins user without any HTML and JS stuff. I will probably create ZeroNet PR for this in near future.
In the meantime, you have to manually login into ZeroNet instance from web interface. This will save private key so you will be able to use it from ZeroFramePy.
I have found the solution.
To use master address / master seed first of all you have to use your current address which has been sent in cookie to login
How multiuser works?
- When you go first time to ZeroNet you received session from server. It means in ZeroNet instance user has been created
set-cookie: master_address=XXXXXXXXX;path=/;max-age=2592000;
- When you use API you have to send cookie
master_address=XXXXXXXXX
How my patch works?
- Download page to get
wrapper_key
from source code and also get value of current logged user in cookiemaster_address
- Use
master_address
andwrapper_key
from step 1 and make web socket connection - Change user - cmd
userLoginForm
and sendmaster_seed
of address which you want to make request -multiuser_master_seed
- Reconnect to API using
master_address
which you want to make requestsmultiuser_master_address
. - No
{'error': 'No user found'}
anymore
Now everything is working.
Please see on my ugly code - https://github.com/krzotr/ZeroFramePy/commit/31ff595719bf884587e0ed9f33a357762f14b945
@krzotr Thank you for your code! I will check it, clean it up a bit and include it here.
@krzotr Sorry for the delay but I didn't have mich time to do this. It should now be fixed in 85906fd. Can you check it so I can release changes as a new version?
Although code may look more complicated, it is needed to support:
- Instance without Multiuser plugin.
- Instance with Multiuser plugin with account provided by instance.
- Instance with Multiuser plugin with account address provided by user (account must already exist).
- Instance with Multiuser plugin with account address and seed provided by user (account will be created).
I will also port the changes to JS version (I hope soon) and refactor the whole library to be more modular (some time later).