Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
2.5 kB · 82 lines
Elixir
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283defmodule GitSyncWeb.GithubController do use GitSyncWeb, :controller
alias GitSync.Connection alias GitSync.Connections alias GitSync.Github.OAuth alias GitSyncWeb.ConnectionController alias GitSyncWeb.RedirectUri
@state_key "github_oauth_state"
plug :require_github when action in [:authorize, :callback, :delete]
def create(conn, %{"connection" => params}) do case Connections.enable_github(params) do {:ok, _connection} -> conn |> put_flash(:info, "GitHub OAuth application saved. Connect it to grant access.") |> redirect(to: ~p"/connections")
{:error, changeset} -> ConnectionController.render_index(conn, github_form: ConnectionController.form(changeset)) end end
def authorize(%Plug.Conn{assigns: %{github: github}} = conn, _params) do state = OAuth.state()
conn |> put_session(@state_key, state) |> redirect(external: OAuth.authorize_url(github, RedirectUri.github_callback(conn), state)) end
def callback(conn, %{"code" => code, "state" => state}) do expected = get_session(conn, @state_key) || "" conn = delete_session(conn, @state_key)
if Plug.Crypto.secure_compare(state, expected) do exchange(conn, code) else failed(conn, "the state parameter did not match") end end
def delete(%Plug.Conn{assigns: %{github: github}} = conn, _params) do {:ok, _connection} = Connections.disconnect(github)
conn |> put_flash(:info, "GitHub disconnected.") |> redirect(to: ~p"/connections") end
defp exchange(%Plug.Conn{assigns: %{github: github}} = conn, code) do with {:ok, token} <- OAuth.exchange_code(github, code, RedirectUri.github_callback(conn)), {:ok, _connection} <- Connections.store_token(github, token) do conn |> put_flash(:info, "GitHub connected.") |> redirect(to: ~p"/connections") else {:error, reason} -> failed(conn, reason) end end
defp failed(conn, reason) do conn |> put_flash(:error, "Could not connect GitHub: #{reason}") |> redirect(to: ~p"/connections") end
defp require_github(conn, _opts) do case Connections.github() do %Connection{client_id: client_id} = github when is_binary(client_id) -> assign(conn, :github, github)
_ -> conn |> put_flash(:error, "GitHub is not enabled yet.") |> redirect(to: ~p"/connections") |> halt() end endend