danschultzer / phoenix_oauth2_provider

Get an OAuth 2 provider running in your phoenix with controllers, views and models in just two minutes
MIT License
84 stars 41 forks source link

How can I do tests in my controller? #36

Closed lucasbesen closed 4 years ago

lucasbesen commented 4 years ago

I'm trying to do some tests in my controller with a authenticated user.

Trying to use this config:

setup %{conn: conn} do
  user = %User{email: "test@example.com"}
  conn = Pow.Plug.assign_current_user(conn, user, otp_app: :my_app)

  {:ok, conn: conn}
end
danschultzer commented 4 years ago

What controller actions are you testing? And what error do you experience?

lucasbesen commented 4 years ago

@danschultzer simple actions, like create and fetch.

I’m just receiving unauthenticated error

danschultzer commented 4 years ago

Are you testing OAuth 2 provider endpoints or api routes that are using e.g. ExOauth2Provider.Plug.VerifyHeader?

lucasbesen commented 4 years ago

@danschultzer api protected routes, not OAuth ones

danschultzer commented 4 years ago

With an OAuth 2.0 API you have a resource owner, a resource owner can also be a client rather than a user. See the docs here for how to fetch the current resource owner: https://github.com/danschultzer/ex_oauth2_provider#current-resource-owner-and-access-token

You could generate an access token with preloaded resource owner and then use the plug to set it, like this:

setup %{conn: conn} do
  resource_owner = 
    %User{}
    |> Ecto.Changeset.change(email: "test@example.com")
    |> MyApp.Repo.insert!()

  {:ok, access_token} = ExOauth2Provider.AccessTokens.create_token(resource_owner, %{scopes: "read write"}, otp_app: :my_app)
  access_token = MyApp.Repo.preload(access_token, [:resource_owner])

  conn = ExOauth2Provider.Plug.set_current_access_token(conn, access_token)

  {:ok, conn: conn}
end

You may also want to create an application and add it to the create_token params.

You can fetch the current resource owner by calling ExOauth2Provider.Plug.current_resource_owner(conn)

lucasbesen commented 4 years ago

Still having Unauthenticated error, but now I have the auth object inside my conn

%Plug.Conn{
  adapter: {Plug.Adapters.Test.Conn, :...},
  assigns: %{},
  before_send: [],
  body_params: %Plug.Conn.Unfetched{aspect: :body_params},
  cookies: %Plug.Conn.Unfetched{aspect: :cookies},
  halted: false,
  host: "www.example.com",
  method: "GET",
  owner: #PID<0.556.0>,
  params: %Plug.Conn.Unfetched{aspect: :params},
  path_info: [],
  path_params: %{},
  port: 80,
  private: %{
    ex_oauth2_provider_default_access_token: %MyApp.OauthAccessTokens.OauthAccessToken{
      __meta__: #Ecto.Schema.Metadata<:loaded, "oauth_access_tokens">,
      application: #Ecto.Association.NotLoaded<association :application is not loaded>,
      application_id: nil,
      expires_in: 7200,
      id: 3,
      inserted_at: ~N[2019-11-14 13:20:18],
      previous_refresh_token: "",
      refresh_token: nil,
      resource_owner: %MyApp.Users.User{
        __meta__: #Ecto.Schema.Metadata<:loaded, "users">,
        confirm_password: nil,
        current_password: nil,
        email: "test@example.com",
        id: 4,
        inserted_at: ~N[2019-11-14 13:20:18],
        password: nil,
        password_hash: nil,
        updated_at: ~N[2019-11-14 13:20:18]
      },
      resource_owner_id: 4,
      revoked_at: nil,
      scopes: "",
      token: "de25ba731b787c27325924a4adfdfc528e748017aba0372e943e0e3185894296",
      updated_at: ~N[2019-11-14 13:20:18]
    },
    phoenix_recycled: true,
    plug_skip_csrf_protection: true
  },
  query_params: %Plug.Conn.Unfetched{aspect: :query_params},
  query_string: "",
  remote_ip: {127, 0, 0, 1},
  req_cookies: %Plug.Conn.Unfetched{aspect: :cookies},
  req_headers: [{"content-type", "application/json"}],
  request_path: "/",
  resp_body: nil,
  resp_cookies: %{},
  resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}],
  scheme: :http,
  script_name: [],
  secret_key_base: nil,
  state: :unset,
  status: nil
}
danschultzer commented 4 years ago

How does the API pipeline in your routes look?

There's also a previous issue for this: https://github.com/danschultzer/phoenix_oauth2_provider/issues/25

lucasbesen commented 4 years ago

This issue helped me, thanks!