Bouncers and Managed Accounts

An idea I’ve had in the back of my mind for a bit is how to handle IRC bouncers and other similar ideas. Yes part of this is to look at making the detachable libpurple front end we’ve been after for ever.

Anyways, the main idea has been to create a protocol plugin for each bouncer. That is protocol plugins for Soju, Weechat, ZNC, Quassel, etc. You would then add your account with those bouncers which would then create and manage the accounts for each network/service in the bouncer. This could potentially also be used to manage bridges and stuff.

I’ve specifically been looking at this method because while something like BouncerServ is workable, it’s not a great user experience. Also I personally stopped using ZNC awhile back because it confused my networks and ended up creating all of the channels I was in on Freenode (RIP) on a Slack instance I was using via the IRC gateway.

This is/was a privacy nightmare, so avoiding that is ideal, and having separate accounts for each network on a bouncer is probably the best separation we can do at least at the UI level.

However, having separate accounts gets complicated quickly. Having an account manage other accounts isn’t anything crazy, the API is all available to it after all. But managing connections might be a huge problem if for example you just have a single connection that gets multiplexed to include all your networks. I know not all IRC bouncers do this but they might be able to? I’m not super well versed here..

Anyways, the other issue is password management and other settings. Do we store the in the password manager from the top level protocol for each account it’s managing? Do we forward setting changes up through the bouncer or make them readonly on the purple side?

Also for the cases where there’s only one connection we might be able to separate out the accounts by implementing a custom GProxyResolver to route the protocol through the bouncer, but this is something that’d get crazy quick.

For example, say I have a Soju account that has a libera network. The Soju protocol plugin would create an IRCv3 account with the custom proxy resolver and a server that the Soju protocol can identify, then it could decide what to with each sent message and the route each received message. Effectively turing the Soju account into a local server.

These are just some of my random thoughts on this. Please let me know if you have any questions or have anything to add or if I’m completely wrong about anything :slight_smile:

Look at soju.py for weechat they create full “accounts” for each network.

If we went this route, the soju protocol would use ibis to connect to soju and then get the networks. Then for each network found, new new IRCv3 account would be created with a sasluser name with the following format <sasl_username>/<soju network name>. Then if the password is stored, we would write it to the credential manager for the new account and then enable it.

I need to play around with this a bit, but it seems like this will work well enough for now at least.

Yeah that’s what I had in mind and tried to explain in the MVP post.

1 Like

Alright, I’ve got some pr’s to stack up but once they land and we release this will work pretty well. The idea is the soju account will never bind to a network so it’ll just handle notifications and stuff and do it’s thing. We can have it provide a status conversation for interaction and we’ll add an account setting for the client name to use everywhere.

grim@spectre:~/p/ibis/build$ ./ibis-cli/ibis-cli -s soju -p 6697 -n cli-test -t -I --sasl-username soju --sasl-password abc123 --require-sasl -C soju.im/bouncer-networks -c "BOUNCER listnetworks" -c "join #pidgin"
** Message: 17:19:32.035: TLS connection established
17:19:32 > CAP LS 302
17:19:32 > USER cli-test 0 * cli-test
17:19:32 > NICK cli-test
17:19:32 < :soju CAP * LS :invite-notify batch setname sasl=PLAIN draft/chathistory draft/extended-monitor soju.im/bouncer-networks-notify cap-notify soju.im/account-required draft/metadata-2=before-connect,max-keys=0,max-value-bytes=1 draft/no-implicit-names soju.im/read draft/read-marker soju.im/bouncer-networks server-time soju.im/no-implicit-names account-tag chghost extended-monitor away-notify extended-join multi-prefix echo-message soju.im/webpush draft/pre-away soju.im/search account-notify message-tags
17:19:32 > CAP REQ batch
17:19:32 > CAP REQ soju.im/bouncer-networks
17:19:32 > CAP REQ sasl
17:19:32 > CAP REQ cap-notify
17:19:32 > CAP REQ message-tags
17:19:32 < :soju CAP * ACK batch
17:19:32 < :soju CAP * ACK soju.im/bouncer-networks
17:19:32 < :soju CAP * ACK sasl
Ibis-Message: 17:19:32.037: trying SASL 'PLAIN' mechanism
17:19:32 > AUTHENTICATE PLAIN
17:19:32 < :soju CAP * ACK cap-notify
17:19:32 < :soju CAP * ACK message-tags
17:19:32 > CAP REQ server-time
17:19:32 < :soju AUTHENTICATE +
17:19:32 > AUTHENTICATE AHNvanUAYWJjMTIz
17:19:32 < :soju CAP * ACK server-time
17:19:32 < :soju 903 * :SASL authentication successful
Ibis-Message: 17:19:32.106: successfully authenticated with SASL 'PLAIN' mechanism.
17:19:32 > CAP END
17:19:32 < :soju 001 soju :Welcome to soju, soju
17:19:32 > BOUNCER listnetworks
17:19:32 < :soju 002 soju :Your host is soju
17:19:32 > JOIN #pidgin
17:19:32 < :soju 004 soju soju soju aiwroO OovaimnqpsrtklbeI
17:19:32 < :soju 005 * soju.im/SAFERATE BOT=B CASEMAPPING=ascii WHOX CHANTYPES= LINELEN=4096 :are supported
17:19:32 < :soju 221 soju +o
17:19:32 < :soju 900 soju soju!soju@X.X.X.X soju :You are logged in as soju
17:19:32 < :soju 422 soju :No MOTD
17:19:32 < :soju BATCH +1 soju.im/bouncer-networks
17:19:32 < :soju BATCH -1

(ibis-cli:3501079): Ibis-WARNING **: 17:19:32.107: batch '1' was not handled, replaying manually
17:19:32 < @batch=1 :soju BOUNCER NETWORK 1 name=ergo;state=connected;nickname=soju;realname=soju;tls=0;host=192.168.1.220;port=6667

(ibis-cli:3501079): Ibis-WARNING **: 17:19:32.107: finished manually replaying batch '1'
17:19:32 < :soju 400 * JOIN :Cannot interact with channels and users on the bouncer connection. Did you mean to use a specific network?