165 lines
5.0 KiB
Elixir
165 lines
5.0 KiB
Elixir
defmodule Mobilizon.GraphQL.Resolvers.Application do
|
|
@moduledoc """
|
|
Handles the Application-related GraphQL calls.
|
|
"""
|
|
|
|
alias Mobilizon.Applications, as: ApplicationManager
|
|
alias Mobilizon.Applications.{Application, ApplicationDeviceActivation, ApplicationToken}
|
|
alias Mobilizon.GraphQL.Error
|
|
alias Mobilizon.Service.Auth.Applications
|
|
alias Mobilizon.Users.User
|
|
import Mobilizon.Web.Gettext, only: [dgettext: 2]
|
|
|
|
require Logger
|
|
|
|
@doc """
|
|
Authorize an application
|
|
"""
|
|
@spec authorize(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()} | {:error, String.t()}
|
|
def authorize(
|
|
_parent,
|
|
%{client_id: client_id, redirect_uri: redirect_uri, scope: scope} = args,
|
|
%{context: %{current_user: %User{id: user_id}}}
|
|
) do
|
|
case Applications.autorize(client_id, redirect_uri, scope, user_id) do
|
|
{:ok,
|
|
%ApplicationToken{
|
|
application: %Application{client_id: client_id},
|
|
scope: scope,
|
|
authorization_code: code
|
|
}} ->
|
|
{:ok, %{code: code, state: Map.get(args, :state), client_id: client_id, scope: scope}}
|
|
|
|
{:error, %Ecto.Changeset{} = err} ->
|
|
{:error, err}
|
|
|
|
{:error, :application_not_found} ->
|
|
{:error,
|
|
dgettext(
|
|
"errors",
|
|
"No application with this client_id was found"
|
|
)}
|
|
|
|
{:error, :redirect_uri_not_in_allowed} ->
|
|
{:error,
|
|
dgettext(
|
|
"errors",
|
|
"The given redirect_uri is not in the list of allowed redirect URIs"
|
|
)}
|
|
end
|
|
end
|
|
|
|
def authorize(_parent, _args, _context) do
|
|
{:error, :unauthenticated}
|
|
end
|
|
|
|
@spec get_application(any(), map(), Absinthe.Resolution.t()) ::
|
|
{:ok, Application.t()} | {:error, :application_not_found | :unauthenticated}
|
|
def get_application(_parent, %{client_id: client_id}, %{context: %{current_user: %User{}}}) do
|
|
case ApplicationManager.get_application_by_client_id(client_id) do
|
|
%Application{} = application ->
|
|
{:ok, application}
|
|
|
|
nil ->
|
|
{:error, :application_not_found}
|
|
end
|
|
end
|
|
|
|
def get_application(_parent, _args, _resolution) do
|
|
{:error, :unauthenticated}
|
|
end
|
|
|
|
def get_user_applications(_parent, _args, %{context: %{current_user: %User{id: user_id}}}) do
|
|
{:ok, ApplicationManager.list_application_tokens_for_user_id(user_id)}
|
|
end
|
|
|
|
def get_user_applications(_parent, _args, _resolution) do
|
|
{:error, :unauthenticated}
|
|
end
|
|
|
|
def revoke_application_token(_parent, %{app_token_id: app_token_id}, %{
|
|
context: %{current_user: %User{id: user_id}}
|
|
}) do
|
|
case ApplicationManager.get_application_token(app_token_id) do
|
|
%ApplicationToken{user_id: ^user_id} = app_token ->
|
|
case Applications.revoke_application_token(app_token) do
|
|
{:ok, %{delete_app_token: app_token, delete_guardian_tokens: _delete_guardian_tokens}} ->
|
|
{:ok, %{id: app_token.id}}
|
|
|
|
{:error, _, _, _} ->
|
|
{:error, dgettext("errors", "Error while revoking token")}
|
|
end
|
|
|
|
_ ->
|
|
{:error, :application_token_not_found}
|
|
end
|
|
end
|
|
|
|
def revoke_application_token(_parent, _args, _resolution) do
|
|
{:error, :unauthenticated}
|
|
end
|
|
|
|
def activate_device(_parent, %{user_code: user_code}, %{
|
|
context: %{current_user: %User{} = user}
|
|
}) do
|
|
case Applications.activate_device(user_code, user) do
|
|
{:ok, %ApplicationDeviceActivation{} = app_device_activation} ->
|
|
{:ok, app_device_activation |> Map.from_struct() |> Map.take([:application, :id, :scope])}
|
|
|
|
{:error, :expired} ->
|
|
{:error,
|
|
%Error{
|
|
message: dgettext("errors", "The given user code has expired"),
|
|
status_code: 400,
|
|
code: :device_application_code_expired
|
|
}}
|
|
|
|
{:error, :not_found} ->
|
|
{:error, dgettext("errors", "The given user code is invalid")}
|
|
end
|
|
end
|
|
|
|
def activate_device(_parent, _args, _resolution) do
|
|
{:error, :unauthenticated}
|
|
end
|
|
|
|
@spec authorize_device_application(any(), map(), Absinthe.Resolution.t()) ::
|
|
{:ok, map()} | {:error, String.t()}
|
|
def authorize_device_application(
|
|
_parent,
|
|
%{client_id: client_id, user_code: user_code},
|
|
%{context: %{current_user: %User{}}}
|
|
) do
|
|
case Applications.autorize_device_application(client_id, user_code) do
|
|
{:ok, %ApplicationDeviceActivation{application: app}} ->
|
|
{:ok, app}
|
|
|
|
{:error, :not_confirmed} ->
|
|
{:error,
|
|
dgettext(
|
|
"errors",
|
|
"The device user code was not provided before approving the application"
|
|
)}
|
|
|
|
{:error, :not_found} ->
|
|
{:error,
|
|
dgettext(
|
|
"errors",
|
|
"The given user code is invalid"
|
|
)}
|
|
|
|
{:error, :expired} ->
|
|
{:error,
|
|
%Error{
|
|
message: dgettext("errors", "The given user code has expired"),
|
|
status_code: 400,
|
|
code: :device_application_code_expired
|
|
}}
|
|
end
|
|
end
|
|
|
|
def authorize_device_application(_parent, _args, _resolution) do
|
|
{:error, :unauthenticated}
|
|
end
|
|
end
|