Open dwrensha opened 7 years ago
The docs you link appear to be OAuth1, which required that the Authorization
header contain a signature generated by a convoluted mechanism. Under OAuth2, the Authorization
header is just Authorization: Bearer <token>
. In the latter case -- assuming Twitter supports OAuth2 -- you should be able to get access to the API through the Powerbox today by punching in https://api.twitter.com#<token>
as the custom URL in the powerbox UI. You will need to obtain an access token manually, which usually involves POSTing to some endpoint and providing your client key, client secret, etc.
Of course, we don't really want users to copy/paste, much less manually obtain access tokens; we'd rather provide a nice UI. I think the right answer here is to add Twitter as another authentication provider. The Sandstorm server admin would need to obtain a client key and secret, but individual users would not. We may want to implement the identities/credentials/personas refactor before we add any more identity providers, though...
I was reading a bit how the OAuth Powerbox stuff works while reading around #3180 (cc: @zenhack) and it caused me to think a bit about the login providers limitations and how it impacts this. (#3074 also represents a common request for this, going all the way back to #525.)
In my case, I choose not to let Google know much about my Sandstorm server, so I didn't configure Google login. I didn't realize this adds the secondary limitation that apps that want to talk to Google's API also can't. Can I choose to configure an OAuth service and still disallow Sandstorm users for using it for login?
I do not know if anyone in their right mind would want to let people use Facebook login to Sandstorm (same thoughts about Google as far as I'm concerned, but whatever), but people might want a Facebook OAuth configuration so that they can pull data from it. I was thinking about exporting data from Fitbit (before it also becomes Google), but adding a Fitbit login provider to Sandstorm would be kinda silly, in my opinion.
Right now, login providers (and hence OAuth providers) are very much hardcoded into Sandstorm and unable to be added by the server admin, much less the Sandstorm user. And if we want to enable Sandstorm to manage our OAuth flow to various services, we probably need a better story around doing this?
It does seem reasonable to uncouple login providers from stuff the server can talk to via oauth, and there's no reason we couldn't do that I think. It would somewhat sidestep the issue of just having too many and being overwhelming.
Right now, login providers (and hence OAuth providers) are very much hardcoded into Sandstorm and unable to be added by the server admin, much less the Sandstorm user. And if we want to enable Sandstorm to manage our OAuth flow to various services, we probably need a better story around doing this?
I'm not sure what that story would be; OAuth is obnoxiously not quite standard enough to just be able to plug in an arbitrary provider to an app without any dev work. It's not hard to add one, but I don't know how you'd automate it. Though I agree with the goal...
Another concern or two I was thinking about:
Do we want to be in a situation where a user must ask their server admin to setup keys so they can use a new app that talks to an API? If we standardize on using keys held by the server, and that's what apps use, we can expect that problem often.
What if I have Google login on my server, and then someone uploads an app that abuses the Google API and violates the ToS. Does Google ban my client ID and prevent my users from logging in? Does Google torch my account, delete my Gmail and my Play purchases? Are there risks to letting arbitrary apps use my API keys?
As for implementation:
The question about admins possibly being on the hook for ToS violations from users is a good one, we should think about how to deal with that.
I haven't dug into meteor-accounts much at all, so can't comment on that yet.
There is an idea mentioned in the contributing doc about apps being able to provide auth backends:
https://github.com/sandstorm-io/sandstorm/blob/master/CONTRIBUTING.md#new-authentication-mechanisms
...but for that matter, the oauth powerbox requests are just regular powerbox requests that sandstorm itself can also respond do. It is in principle possible to add apps do to extend functionality, though that being a good experience is going to probably depend on other improvements.
I think it would make sense for admins to be able to enable Google (or whatever) credentials, but refuse to let them be used for login. (Users would only be able to add them as non-login credentials.)
Unfortunately OAuth 2.0 is not quite specific enough that administrators could configure arbitrary login providers. E.g. the URLs of the various endpoints differ from provider to provider, with no real pattern. :( You can look at the various per-provider Meteor packages to see how much customization is needed for each... it's not a ton but it's still painful.
The policy stuff around client keys and ToS violations has always been a shitshow for decentralized applications. E.g. when you ship a client app that embeds its own keys, anyone can pull out those keys and use them for any purpose. The whole system was designed for a world where everything is SaaS. :( But I think in practice the kinds of abuse that providers try to manage by blocking client keys are not likely to come from a Sandstorm app...
I had been hoping that the recent powerbox improvements would allow me to write an app that posts tweets through
https://api.twitter.com
. My working assumption was that Twitter would let me generate a token from its UI and that I would be able to directly use that token in aBasic
orBearer
authorization header on a request to the/statuses/update
endpoint.The situation turns out to not be quite so simple. Twitter's "application only" authorization works more or less as I was hoping, but it only allows access to a restricted subset of Twitter's API, and in particular does not allow tweets to be posted.
Twitter's main authorization scheme is more complicated. (See https://dev.twitter.com/oauth/overview/authorizing-requests and https://dev.twitter.com/oauth/overview/single-user.) Based on my current understanding of it, I can roughly imagine two ways that it might work with Sandstorm.
The user generates their own Twitter "application" through https://apps.twitter.com/ and then generates an "access token" through the UI there. When the Sandstorm grain makes a powerbox request for
https://api.twitter.com
, there is a configuration step where the user enters the "Consumer Key", the "Consumer Secret", the "Access Token", and the "Access Token Secret" from their "application". Sandstorm stores these values (encrypted) and uses them to fill out theAuthorization
header for each request.The Sandstorm server itself is a Twitter "application", similar to how it is a Github application when Github Oauth is configured. In fact, we could make Twitter an identity provider. However, this Twitter "application" will need to be allowed to do more than just read profile information -- we want it to be able to post tweets. Once this is configured, the powerbox request flow should consist of a few easy clicks, rather than the cumbersome copy-pasting in approach (1). Moreover, the user does not need to be instructed about how to configure their own Twitter "application". A downside is that this approach will probably require a lot more work on our end, to get all of the Oauth integration working smoothly.
If I end up pushing forward on my Twitterbot Sandstorm app, I think I'll start with trying approach (1).