Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Shared sandboxes #1

Open
trezy opened this issue Sep 30, 2020 · 6 comments
Open

[RFC] Shared sandboxes #1

trezy opened this issue Sep 30, 2020 · 6 comments
Assignees

Comments

@trezy
Copy link
Contributor

trezy commented Sep 30, 2020

Authors @trezy
To be reviewed by 06 October, 2020

Need

Developers using fdgt to develop their Twitch applications (bots, overlays, extensions, etc) are often confused by the way that fdgt sandboxes connections. A common refrain is, "I've connected my bot to fdgt... now how do I connect with a chat client to send commands?" This confusion is caused because every connection is isolated inside of its own sandbox. This creates two important conditions:

  1. The benefit is that commands sent to one connection won't affect other connections (e.g., When Bob sends a command, Sally won't see the effects of that command because their connections are completely isolated.
  2. The downside is that developers can't have multiple clients interact with each other. A command scenario would be a streamer creating both a bot and an overlay. Events triggered by the chat connection should trigger actions in both the overlay and the bot simultaneously. This is currently impossible because of the isolated sandbox.

To clear up this confusion and introduce the functionality that developers expect, we need to allow multiple clients to share a sandbox.

Approach

To introduce shared sandboxes, we'll need a few new pieces of infrastructure to be implemented. These span both the fdgt API and website.

  1. Accounts/Logins
    To create and manage shared sandboxes, users will need to create a fdgt account (not necessarily custom accounts, could also be login with a third party account like Google, Twitter, Github, or Twitch). This allows us to track who is using shared sandboxes in case we need to lock down accounts that are abusing the system.
  2. Sandbox Storage
    Connections to fdgt will remain isolated in code, but they will be connected by a backend that shares data to all connections that are using the same sandbox.
  3. Programmatic Sandbox API
    We'll want to create a new API endpoint that allows users to create new sandboxes programmatically. This will be helpful for automated tests to spin create a new sandbox for a test instance, then delete that sandbox after the tests have finished.

Benefits

Introducing shared sandboxes will allow the testing of multiple different scenarios...

Simple manual testing and interaction

When testing a bot against the actual Twitch API, developers can connect their application and a chat client and affect the application by sending messages from their client. Currently, there is no way for multiple clients to interact via the fdgt chat API. This prevents developers from using simple manual testing to verify their connections to fdgt before writing full-fledged tests.

Automated testing

Currently, testing an application against fdgt requires commands to be sent on the same connection as the application being tested. This is problematic if the tests are watching that connection to verify message sending/receipt, or if the framework connecting the application to fdgt needs to be monkey patched to allow the connection to be shared.

Interacting clients

It's not difficult to imagine a developer creating a bot and an overlay and making them both react to the same commands in chat. A contrived example might be a bot that updates a counter field in a database when the !count command is called, while that same command causes the overlay to update an on-screen counter.

Alternatives

Remove sandboxes

This is just a straight up bad idea, but here's the pitch: instead of creating personalized sandboxes, we would remove sandboxes entirely and encourage users to create unique rooms for their test suites.

This is the worst of ideas because it virtually encourages abuse. One user could, in theory, create an application that brute force connects to channels, then sends random messages. This would interfere anytime the application connects to a channel that is currently in use by a test suite. The application could also capture any data sent on the channel, potentially exposing sensitive data that was expected to be sent in secret.

Acknowledgements

Big thanks to @callowcreation, @sadmoody, and @Layla-P for helping flesh out the need for this upgrade

@trezy trezy added the wip label Sep 30, 2020
@trezy trezy self-assigned this Sep 30, 2020
@sadmoody
Copy link

sadmoody commented Oct 1, 2020

You're overthinking it imo @trezy ! One of the nice things about fdgt is that you don't need to change anything except for the server in order for you to connect to it. I think that part of the workflow should remain. Going down the road of user accounts will add an additional barrier to "just getting it working".

I wonder if there's something in the setups already - whether you can use an immediately hashed OAuth token that people have already set up to access a different sandbox. The potential number of hashes that can be created out of the token that's sent to you anyway should be so large that its not worth bruteforcing.

Or maybe even allowing for a subsubdomain to determine the sandbox you join. That way, if someone wants to test something with another user (say, live on twitch), they can easily configure the subsubdomain so that they can connect to the same sandbox.

@trezy
Copy link
Contributor Author

trezy commented Oct 1, 2020

@sadmoody I really like the subsubdomain idea. That's a keeper, I think. In terms of implementation details, I've been wrestling a bit with how applications would connect to the shared sandbox. Other strategies I had considered...

  • Leveraging the PASS command to receive a fdgt token. The issue here is that at some point I'd like to allow the user to add a query parameter telling fdgt to validate the token with Twitch, and react appropriately if it's invalid. Using the PASS command to shared sandboxes would cause problems with that functionality.
  • Using an Authorization header to receive a fdgt token. This would require libraries to support passing custom headers with the connection, which isn't something any of them currently do.
  • Using a query parameter to receive an ID for a sandbox. This probably isn't any different than the subsubdomain route. Maybe I'll just add support for both? 🤔

I wonder if there's something in the setups already - whether you can use an immediately hashed OAuth token that people have already set up to access a different sandbox. The potential number of hashes that can be created out of the token that's sent to you anyway should be so large that its not worth bruteforcing.

I'm not sure I follow on this. Are you saying that fdgt would generate a token when a connection is created, then that token could be used by other applications to connect to the same sandbox? Or that we should support arbitrary tokens, so a test suite could theoretically generate a new token before it connects and use the same token with multiple applications?

@sadmoody
Copy link

sadmoody commented Oct 1, 2020

I'm not sure I follow on this. Are you saying that fdgt would generate a token when a connection is created, then that token could be used by other applications to connect to the same sandbox?

An IRC client cannot connect to the twitch server without supplying an OAuth token. You can use that token to determine the sandbox it gets. So if you want to connect two clients together, they'll both have the same OAuth token. This is already being sent to fdgt as a PASS once a client is connected. Since most of the time, this OAuth token is already there and unique to each person, you can just hash it so you're not storing it on your side in an unsafe way, and use that instead of the subsubdomain.

With that, you'll essentially convert the authentication part of the connection sequence into determining which sandbox the client ends up entering. (i.e. they go to the one which is a hash of whatever they send you as a password - which will be their OAuth token).

That being said, people are sending you their OAuth creds when they connect to fdgt are they not? That's possibly a problem (probably not yours), but I'm not sure what you can do about it exactly.

I still think a subsubdomain is a cleaner solution here.

@AlcaDesign
Copy link

An IRC client cannot connect to the twitch server without supplying an OAuth token.

You are definitely able to connect without an OAuth token.

@trezy
Copy link
Contributor Author

trezy commented Oct 1, 2020

@sadmoody As @AlcaDesign, you can indeed connect without a token.

The issue I'm referring to, though, is that a user may want to perform E2E tests with multiple applications, i.e. multiple tokens. That user should still be able to connect both applications to the sandbox without having to modify anything other than the domain. I think you're right that the subsubdomain approach is still the best option.

@sadmoody
Copy link

sadmoody commented Oct 1, 2020

You are definitely able to connect without an OAuth token.

My mistake, @AlcaDesign and @trezy - I've only had very limited exposure to connections to Twitch chat and my memory of my experience is fuzzy. It was all on stream and done in haste!

If that's the case, then it looks like your two options are either a token/account based approach, or a subsubdomain approach. I'm much more in favour of the latter as it removes additional steps. From a networking/business perspective, it may be valuable to force people to create accounts in order for you to have their emails at least.

You can take both approaches. Do the subsubdomain thing. When people connect to a chatroom, you can send a message to the chatroom on join saying "thank you for using fdgt. you are welcome to continue using this for free. buy me a coffee at _____. If you would like to remove this message, create a free account at link and use the token, otherwise, feel free to ignore" or something a bit more eloquent than that. It'll be pretty non-intrusive, it'll give people a path to removing it, and best of all, not really matter if they don't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants