Merge branch 'fix-user-suspension' into 'master'

Fix user suspension

Closes #374

See merge request framasoft/mobilizon!546
This commit is contained in:
Thomas Citharel 2020-08-18 17:42:30 +02:00
commit 9f3c287e06
4 changed files with 52 additions and 22 deletions

View File

@ -80,6 +80,14 @@ export const DELETE_ACCOUNT = gql`
} }
`; `;
export const SUSPEND_USER = gql`
mutation SuspendUser($userId: ID) {
deleteAccount(userId: $userId) {
id
}
}
`;
export const CURRENT_USER_CLIENT = gql` export const CURRENT_USER_CLIENT = gql`
query { query {
currentUser @client { currentUser @client {

View File

@ -59,7 +59,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Vue, Prop } from "vue-property-decorator"; import { Component, Vue, Prop } from "vue-property-decorator";
import { GET_USER, DELETE_ACCOUNT } from "../../graphql/user"; import { GET_USER, SUSPEND_USER } from "../../graphql/user";
import { usernameWithDomain } from "../../types/actor/actor.model"; import { usernameWithDomain } from "../../types/actor/actor.model";
import RouteName from "../../router/name"; import RouteName from "../../router/name";
import { IUser, ICurrentUserRole } from "../../types/current-user.model"; import { IUser, ICurrentUserRole } from "../../types/current-user.model";
@ -148,7 +148,7 @@ export default class AdminUserProfile extends Vue {
async deleteAccount() { async deleteAccount() {
await this.$apollo.mutate<{ suspendProfile: { id: string } }>({ await this.$apollo.mutate<{ suspendProfile: { id: string } }>({
mutation: DELETE_ACCOUNT, mutation: SUSPEND_USER,
variables: { variables: {
userId: this.id, userId: this.id,
}, },

View File

@ -128,11 +128,33 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
end end
defp convert_changes_to_struct(struct, changes) do defp convert_changes_to_struct(struct, changes) do
with data <- for({key, val} <- changes, into: %{}, do: {String.to_atom(key), val}) do with changeset <- struct.__changeset__,
data <-
for(
{key, val} <- changes,
into: %{},
do: {String.to_atom(key), process_eventual_type(changeset, key, val)}
) do
struct(struct, data) struct(struct, data)
end end
end end
# datetimes are not unserialized as DateTime/NaiveDateTime so we do it manually with changeset data
defp process_eventual_type(changeset, key, val) do
cond do
changeset[String.to_atom(key)] == :utc_datetime and not is_nil(val) ->
{:ok, datetime, _} = DateTime.from_iso8601(val)
datetime
changeset[String.to_atom(key)] == :naive_datetime and not is_nil(val) ->
{:ok, datetime} = NaiveDateTime.from_iso8601(val)
datetime
true ->
val
end
end
def get_dashboard(_parent, _args, %{context: %{current_user: %User{role: role}}}) def get_dashboard(_parent, _args, %{context: %{current_user: %User{role: role}}})
when is_admin(role) do when is_admin(role) do
last_public_event_published = last_public_event_published =

View File

@ -389,6 +389,25 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
end end
end end
def delete_account(_parent, %{user_id: user_id}, %{
context: %{current_user: %User{role: role} = moderator_user}
})
when is_moderator(role) do
with {:moderator_actor, %Actor{} = moderator_actor} <-
{:moderator_actor, Users.get_actor_for_user(moderator_user)},
%User{disabled: false} = user <- Users.get_user(user_id),
{:ok, %User{}} <-
do_delete_account(%User{} = user, Relay.get_actor()) do
Admin.log_action(moderator_actor, "delete", user)
else
{:moderator_actor, nil} ->
{:error, "No actor found for the moderator user"}
%User{disabled: true} ->
{:error, "User already disabled"}
end
end
def delete_account(_parent, args, %{ def delete_account(_parent, args, %{
context: %{current_user: %User{email: email} = user} context: %{current_user: %User{email: email} = user}
}) do }) do
@ -411,25 +430,6 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
end end
end end
def delete_account(_parent, %{user_id: user_id}, %{
context: %{current_user: %User{role: role} = moderator_user}
})
when is_moderator(role) do
with {:moderator_actor, %Actor{} = moderator_actor} <-
{:moderator_actor, Users.get_actor_for_user(moderator_user)},
%User{disabled: false} = user <- Users.get_user(user_id),
{:ok, %User{}} <-
do_delete_account(%User{} = user, Relay.get_actor()) do
Admin.log_action(moderator_actor, "delete", user)
else
{:moderator_actor, nil} ->
{:error, "No actor found for the moderator user"}
%User{disabled: true} ->
{:error, "User already disabled"}
end
end
def delete_account(_parent, _args, _resolution) do def delete_account(_parent, _args, _resolution) do
{:error, "You need to be logged-in to delete your account"} {:error, "You need to be logged-in to delete your account"}
end end