beyond-all-reason / teiserver

Middleware server for online gaming
https://www.beyondallreason.info/
MIT License
46 stars 46 forks source link

Tachyon oauth #335

Open geekingfrog opened 3 weeks ago

geekingfrog commented 3 weeks ago

This implements the two oauth flows required for running tachyon.

There's also at the time of writing, a demo server running at https://tachyon.geekingfrog.com:4567/login

There's currently only one OAuth application registered, with the hardcoded scope tachyon.lobby, one redirect uri: http://127.0.0.1/oauth2callback and the client id is generic_lobby.

The lobby flow

This is using the authorization_code flow.

getting an authorization code

First, the client need to generate a PKCE verifier and challenge. For example:

challenge: "BGLMtLONQ_f6-Z6ikTk8ofWo-cWM3UUeT93LIEG33-M"
verifier: "2ENOENOGA0USUNPROMSUD9U64P604R2LVOVDG5SEL7EIGA5SL3TC2BQN0MJVVG8S"

Then, the client can request an authorization code with a GET request to the endpoint:

https://tachyon.geekingfrog.com:4567/oauth/authorize?response_type=code&code_challenge=BGLMtLONQ_f6-Z6ikTk8ofWo-cWM3UUeT93LIEG33-M&code_challenge_method=S256&client_id=generic_lobby&redirect_uri=http%3A%2F%2F127.0.0.1%2Foauth2callback

You get redirected to a login screen. The demo server has one user with email/password: tachyon@foo.bar and password: tachyonmelon

You then should see a screen to grant access:

2024-06-16-856x269-scrot

Clicking on "Let's go!" redirects to: 127.0.0.1/oauth2callback?code=<code>

exchanging the authorization code for an access token

You can then issue a POST request to

curl -iv https://tachyon.geekingfrog.com:4567/oauth/token \
--data-urlencode "grant_type=authorization_code" \
--data-urlencode "client_id=generic_lobby" \
--data-urlencode "code=60PKPAAVGIL8L6MCSVQK90V1GLORV22PQI6H13PIGQL21E0HFAF0====" \
--data-urlencode "code_verifier=2ENOENOGA0USUNPROMSUD9U64P604R2LVOVDG5SEL7EIGA5SL3TC2BQN0MJVVG8S" \
--data-urlencode "redirect_uri=http://localhost/oauth2callback"

and you get back

{
  "access_token":"C45B3IG4CAHUDG1TAN03USAA55KDS2NA30VQIFLTN9FNMICPA2DG",
  "expires_in":1800,
  "refresh_token":"15IA4J2O0NCH08D6URPK6O3S38G3B7RFBFOPJVV20MNJNHJ11JIG",
  "token_type":"Bearer"
}

the autohost flow

I configured one client_id/client_secret pair that can be used to retrieve an auth token:

curl -ivv "https://tachyon.geekingfrog.com:4567/oauth/token" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=207966ee-6997-433f-a1fa-28da8f3b754e" \
--data-urlencode "client_secret=NENEGFN5MNNA6TH34P53JE88STHA5RCQJ06RKTG5HN92UMAOQ72G"

and this gives the same type of response.

Testing

There are automated tests under 2 location, one for the context and one for the controllers:

mix test test/teiserver/o_auth/
mix test test/teiserver_web/controllers/o_auth

Out of (OAuth) Scope for this PR

p2004a commented 3 weeks ago

:tada: I will review it for sure (don't have perms to assign myself as reviewer)