534 lines
14 KiB
Elixir
534 lines
14 KiB
Elixir
defmodule Mobilizon.GraphQL.Resolvers.ApplicationTest do
|
|
use Mobilizon.Web.ConnCase
|
|
|
|
import Mobilizon.Factory
|
|
require Logger
|
|
|
|
alias Mobilizon.Applications.{Application, ApplicationDeviceActivation}
|
|
alias Mobilizon.GraphQL.AbsintheHelpers
|
|
|
|
@identities_query """
|
|
query LoggedUser {
|
|
loggedUser {
|
|
actors {
|
|
id
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
describe "Authorize an application" do
|
|
@authorize_mutation """
|
|
mutation AuthorizeApplication(
|
|
$applicationClientId: String!
|
|
$redirectURI: String!
|
|
$state: String
|
|
$scope: String!
|
|
) {
|
|
authorizeApplication(
|
|
clientId: $applicationClientId
|
|
redirectURI: $redirectURI
|
|
state: $state
|
|
scope: $scope
|
|
) {
|
|
code
|
|
state
|
|
clientId
|
|
scope
|
|
}
|
|
}
|
|
"""
|
|
test "while being not logged-in", %{conn: conn} do
|
|
res =
|
|
conn
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @authorize_mutation,
|
|
variables: [
|
|
applicationClientId: "an invalid client_id",
|
|
redirectURI: "doesn't matter",
|
|
state: "hello",
|
|
scope: "read"
|
|
]
|
|
)
|
|
|
|
assert "You need to be logged in" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with incorrect client_id", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @authorize_mutation,
|
|
variables: [
|
|
applicationClientId: "an invalid client_id",
|
|
redirectURI: "doesn't matter",
|
|
state: "hello",
|
|
scope: "read"
|
|
]
|
|
)
|
|
|
|
assert "No application with this client_id was found" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with incorrect redirect_uri", %{conn: conn} do
|
|
user = insert(:user)
|
|
app = insert(:auth_application)
|
|
|
|
client_id = app.client_id
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @authorize_mutation,
|
|
variables: [
|
|
applicationClientId: client_id,
|
|
redirectURI: "something not in app's redirect URIs",
|
|
state: "hello",
|
|
scope: "read"
|
|
]
|
|
)
|
|
|
|
assert "The given redirect_uri is not in the list of allowed redirect URIs" =
|
|
hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with correct params", %{conn: conn} do
|
|
user = insert(:user)
|
|
app = insert(:auth_application)
|
|
|
|
client_id = app.client_id
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @authorize_mutation,
|
|
variables: [
|
|
applicationClientId: client_id,
|
|
redirectURI: hd(app.redirect_uris),
|
|
state: "hello",
|
|
scope: "read"
|
|
]
|
|
)
|
|
|
|
assert %{
|
|
"scope" => "read",
|
|
"state" => "hello",
|
|
"clientId" => ^client_id,
|
|
"code" => _code
|
|
} = res["data"]["authorizeApplication"]
|
|
end
|
|
end
|
|
|
|
describe "Revoke an application token" do
|
|
@revoke_mutation """
|
|
mutation RevokeApplicationToken($appTokenId: String!) {
|
|
revokeApplicationToken(appTokenId: $appTokenId) {
|
|
id
|
|
}
|
|
}
|
|
"""
|
|
|
|
test "while not authenticated", %{conn: conn} do
|
|
res =
|
|
conn
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @revoke_mutation,
|
|
variables: [
|
|
appTokenId: "not an actual token ID"
|
|
]
|
|
)
|
|
|
|
assert "You need to be logged in" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with an invalid token", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @revoke_mutation,
|
|
variables: [
|
|
appTokenId: "5846"
|
|
]
|
|
)
|
|
|
|
assert "Application token not found" == hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with valid token", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
app_token = insert(:auth_application_token, user: user)
|
|
app_token_id = to_string(app_token.id)
|
|
|
|
authed_conn = auth_conn(conn, app_token)
|
|
|
|
res = AbsintheHelpers.graphql_query(authed_conn, query: @identities_query)
|
|
assert res["errors"] == nil
|
|
assert res["data"]["loggedUser"]["actors"]
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @revoke_mutation,
|
|
variables: [
|
|
appTokenId: app_token_id
|
|
]
|
|
)
|
|
|
|
assert app_token_id == res["data"]["revokeApplicationToken"]["id"]
|
|
|
|
# Asserting the token can't be used anymore
|
|
res = AbsintheHelpers.graphql_query(authed_conn, query: @identities_query)
|
|
assert "You need to be logged in" == hd(res["errors"])["message"]
|
|
end
|
|
end
|
|
|
|
describe "Get an application" do
|
|
@application_query """
|
|
query AuthApplication($clientId: String!) {
|
|
authApplication(clientId: $clientId) {
|
|
id
|
|
clientId
|
|
name
|
|
website
|
|
}
|
|
}
|
|
"""
|
|
|
|
test "while not authenticated", %{conn: conn} do
|
|
res =
|
|
conn
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @application_query,
|
|
variables: [
|
|
clientId: "not an actual client ID"
|
|
]
|
|
)
|
|
|
|
assert "You need to be logged in" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with incorrect client_id", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @application_query,
|
|
variables: [
|
|
clientId: "nonsense"
|
|
]
|
|
)
|
|
|
|
assert "Application not found" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with valid client_id", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
%Application{id: app_id, client_id: app_client_id, name: app_name, website: app_website} =
|
|
insert(:auth_application)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @application_query,
|
|
variables: [
|
|
clientId: app_client_id
|
|
]
|
|
)
|
|
|
|
assert is_nil(res["errors"])
|
|
|
|
app_id = to_string(app_id)
|
|
|
|
assert %{
|
|
"id" => ^app_id,
|
|
"clientId" => ^app_client_id,
|
|
"name" => ^app_name,
|
|
"website" => ^app_website
|
|
} = res["data"]["authApplication"]
|
|
end
|
|
end
|
|
|
|
describe "Get user applications" do
|
|
@user_apps_query """
|
|
query AuthAuthorizedApplications {
|
|
loggedUser {
|
|
id
|
|
authAuthorizedApplications {
|
|
id
|
|
application {
|
|
name
|
|
website
|
|
}
|
|
lastUsedAt
|
|
insertedAt
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
test "without being logged in", %{conn: conn} do
|
|
res =
|
|
conn
|
|
|> AbsintheHelpers.graphql_query(query: @user_apps_query)
|
|
|
|
assert "You need to be logged in" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with an app token", %{conn: conn} do
|
|
user = insert(:user)
|
|
app_token = insert(:auth_application_token, user: user)
|
|
|
|
insert(:auth_application_token, user: user, status: :success, authorization_code: nil)
|
|
|
|
insert(:auth_application_token, user: user, status: :success, authorization_code: nil)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(app_token)
|
|
|> AbsintheHelpers.graphql_query(query: @user_apps_query)
|
|
|
|
assert is_nil(res["data"]["loggedUser"]["authAuthorizedApplications"])
|
|
refute is_nil(res["data"]["loggedUser"]["id"])
|
|
assert hd(res["errors"])["message"] =~ "Not authorized to access field"
|
|
assert hd(res["errors"])["path"] == ["loggedUser", "authAuthorizedApplications"]
|
|
end
|
|
|
|
test "with authorized applications", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
app_token_1 =
|
|
insert(:auth_application_token, user: user, status: :success, authorization_code: nil)
|
|
|
|
app_token_2 =
|
|
insert(:auth_application_token, user: user, status: :success, authorization_code: nil)
|
|
|
|
# Someone else's app token
|
|
app_token_3 = insert(:auth_application_token, status: :success, authorization_code: nil)
|
|
# An app token not activated
|
|
app_token_4 = insert(:auth_application_token, user: user)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(query: @user_apps_query)
|
|
|
|
assert is_nil(res["errors"])
|
|
assert 2 = length(res["data"]["loggedUser"]["authAuthorizedApplications"])
|
|
|
|
found_app_token_ids =
|
|
res["data"]["loggedUser"]["authAuthorizedApplications"]
|
|
|> Enum.map(&String.to_integer(&1["id"]))
|
|
|> MapSet.new()
|
|
|
|
assert MapSet.subset?(MapSet.new([app_token_1.id, app_token_2.id]), found_app_token_ids)
|
|
refute MapSet.member?(found_app_token_ids, app_token_3.id)
|
|
refute MapSet.member?(found_app_token_ids, app_token_4.id)
|
|
end
|
|
end
|
|
|
|
describe "Device activation" do
|
|
@device_activation_mutation """
|
|
mutation DeviceActivation($userCode: String!) {
|
|
deviceActivation(userCode: $userCode) {
|
|
id
|
|
application {
|
|
id
|
|
clientId
|
|
name
|
|
website
|
|
}
|
|
scope
|
|
}
|
|
}
|
|
"""
|
|
|
|
test "without being logged-in", %{conn: conn} do
|
|
res =
|
|
conn
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_activation_mutation,
|
|
variables: [userCode: "hi"]
|
|
)
|
|
|
|
assert "You need to be logged in" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with a bad code", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_activation_mutation,
|
|
variables: [userCode: "hi"]
|
|
)
|
|
|
|
assert "The given user code is invalid" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with an expired code", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
auth_application_device_activation =
|
|
insert(:auth_application_device_activation, user: user, expires_in: -100)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_activation_mutation,
|
|
variables: [userCode: auth_application_device_activation.user_code]
|
|
)
|
|
|
|
assert "The given user code has expired" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with a valid code", %{conn: conn} do
|
|
user = insert(:user)
|
|
auth_application_device_activation = insert(:auth_application_device_activation, user: nil)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_activation_mutation,
|
|
variables: [userCode: auth_application_device_activation.user_code]
|
|
)
|
|
|
|
assert is_nil(res["errors"])
|
|
|
|
assert res["data"]["deviceActivation"]["application"]["id"] ==
|
|
to_string(auth_application_device_activation.application.id)
|
|
end
|
|
end
|
|
|
|
describe "Device authorization" do
|
|
@device_authorization_mutation """
|
|
mutation AuthorizeDeviceApplication(
|
|
$applicationClientId: String!
|
|
$userCode: String!
|
|
) {
|
|
authorizeDeviceApplication(
|
|
clientId: $applicationClientId
|
|
userCode: $userCode
|
|
) {
|
|
clientId
|
|
scope
|
|
}
|
|
}
|
|
"""
|
|
|
|
test "without being logged in", %{conn: conn} do
|
|
res =
|
|
conn
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_authorization_mutation,
|
|
variables: [applicationClientId: "something", userCode: "wrong"]
|
|
)
|
|
|
|
assert "You need to be logged in" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with a bad code", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_authorization_mutation,
|
|
variables: [applicationClientId: "something", userCode: "wrong"]
|
|
)
|
|
|
|
assert "The given user code is invalid" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with some code that isn't approved", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
auth_application_device_activation =
|
|
insert(:auth_application_device_activation, user: user, status: :pending)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_authorization_mutation,
|
|
variables: [
|
|
applicationClientId: auth_application_device_activation.application.client_id,
|
|
userCode: auth_application_device_activation.user_code
|
|
]
|
|
)
|
|
|
|
assert "The device user code was not provided before approving the application" =
|
|
hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with some expired code", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
auth_application_device_activation =
|
|
insert(:auth_application_device_activation,
|
|
user: user,
|
|
status: :confirmed,
|
|
expires_in: -100
|
|
)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_authorization_mutation,
|
|
variables: [
|
|
applicationClientId: auth_application_device_activation.application.client_id,
|
|
userCode: auth_application_device_activation.user_code
|
|
]
|
|
)
|
|
|
|
assert "The given user code has expired" = hd(res["errors"])["message"]
|
|
end
|
|
|
|
test "with a valid code", %{conn: conn} do
|
|
user = insert(:user)
|
|
|
|
%ApplicationDeviceActivation{
|
|
application: %Application{client_id: client_id},
|
|
user_code: user_code
|
|
} = insert(:auth_application_device_activation, user: user, status: :confirmed)
|
|
|
|
res =
|
|
conn
|
|
|> auth_conn(user)
|
|
|> AbsintheHelpers.graphql_query(
|
|
query: @device_authorization_mutation,
|
|
variables: [
|
|
applicationClientId: client_id,
|
|
userCode: user_code
|
|
]
|
|
)
|
|
|
|
assert is_nil(res["errors"])
|
|
|
|
assert %{
|
|
"clientId" => ^client_id,
|
|
"scope" => _scope
|
|
} = res["data"]["authorizeDeviceApplication"]
|
|
end
|
|
end
|
|
end
|