Delete Tokens and Authorizations on password change
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Sat, 13 Oct 2018 23:45:11 +0000 (01:45 +0200)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Sun, 14 Oct 2018 00:14:54 +0000 (02:14 +0200)
Closes: https://git.pleroma.social/pleroma/pleroma/issues/320
lib/pleroma/user.ex
lib/pleroma/web/oauth/authorization.ex
lib/pleroma/web/oauth/token.ex
test/web/oauth/authorization_test.exs
test/web/oauth/token_test.exs

index db6f96daa43dbc4f832663b6684de82b8305ede2..e972247316c0ad7aed9acf6b6f06857be3133691 100644 (file)
@@ -4,7 +4,7 @@ defmodule Pleroma.User do
   import Ecto.{Changeset, Query}
   alias Pleroma.{Repo, User, Object, Web, Activity, Notification}
   alias Comeonin.Pbkdf2
-  alias Pleroma.Web.{OStatus, Websub}
+  alias Pleroma.Web.{OStatus, Websub, OAuth}
   alias Pleroma.Web.ActivityPub.{Utils, ActivityPub}
 
   schema "users" do
@@ -132,6 +132,9 @@ defmodule Pleroma.User do
       |> validate_required([:password, :password_confirmation])
       |> validate_confirmation(:password)
 
+    OAuth.Token.delete_user_tokens(struct)
+    OAuth.Authorization.delete_user_authorizations(struct)
+
     if changeset.valid? do
       hashed = Pbkdf2.hashpwsalt(changeset.changes[:password])
 
index 23e8eb7b1d81397326b20577ae3a30ff5fad5af0..2cad4550a4f51923bcb0bf938316ab9045636de6 100644 (file)
@@ -4,7 +4,7 @@ defmodule Pleroma.Web.OAuth.Authorization do
   alias Pleroma.{User, Repo}
   alias Pleroma.Web.OAuth.{Authorization, App}
 
-  import Ecto.{Changeset}
+  import Ecto.{Changeset, Query}
 
   schema "oauth_authorizations" do
     field(:token, :string)
@@ -45,4 +45,12 @@ defmodule Pleroma.Web.OAuth.Authorization do
   end
 
   def use_token(%Authorization{used: true}), do: {:error, "already used"}
+
+  def delete_user_authorizations(%User{id: user_id}) do
+    from(
+      a in Pleroma.Web.OAuth.Authorization,
+      where: a.user_id == ^user_id
+    )
+    |> Repo.delete_all()
+  end
 end
index 343fc0c4591619562bf6a48e2a14f112f107c65e..a77d5af35134be1a866b33dfbab38ac3293250b1 100644 (file)
@@ -1,6 +1,8 @@
 defmodule Pleroma.Web.OAuth.Token do
   use Ecto.Schema
 
+  import Ecto.Query
+
   alias Pleroma.{User, Repo}
   alias Pleroma.Web.OAuth.{Token, App, Authorization}
 
@@ -35,4 +37,12 @@ defmodule Pleroma.Web.OAuth.Token do
 
     Repo.insert(token)
   end
+
+  def delete_user_tokens(%User{id: user_id}) do
+    from(
+      t in Pleroma.Web.OAuth.Token,
+      where: t.user_id == ^user_id
+    )
+    |> Repo.delete_all()
+  end
 end
index 4a9e2a3acf105244ca6bf3961de13ea465de9db3..98c7c4133216e258cd626032692ebd1de858ec2d 100644 (file)
@@ -55,4 +55,26 @@ defmodule Pleroma.Web.OAuth.AuthorizationTest do
 
     assert {:error, "token expired"} == Authorization.use_token(expired_auth)
   end
+
+  test "delete authorizations" do
+    {:ok, app} =
+      Repo.insert(
+        App.register_changeset(%App{}, %{
+          client_name: "client",
+          scopes: "scope",
+          redirect_uris: "url"
+        })
+      )
+
+    user = insert(:user)
+
+    {:ok, auth} = Authorization.create_authorization(app, user)
+    {:ok, auth} = Authorization.use_token(auth)
+
+    {auths, _} = Authorization.delete_user_authorizations(user)
+
+    {_, invalid} = Authorization.use_token(auth)
+
+    assert auth != invalid
+  end
 end
index 58448949c88bb8c701430424938193a8fcaab622..f926ff50bf340f32a6d8eab4c48a53ea02aeecd7 100644 (file)
@@ -29,4 +29,36 @@ defmodule Pleroma.Web.OAuth.TokenTest do
     auth = Repo.get(Authorization, auth.id)
     {:error, "already used"} = Token.exchange_token(app, auth)
   end
+
+  test "deletes all tokens of a user" do
+    {:ok, app1} =
+      Repo.insert(
+        App.register_changeset(%App{}, %{
+          client_name: "client1",
+          scopes: "scope",
+          redirect_uris: "url"
+        })
+      )
+
+    {:ok, app2} =
+      Repo.insert(
+        App.register_changeset(%App{}, %{
+          client_name: "client2",
+          scopes: "scope",
+          redirect_uris: "url"
+        })
+      )
+
+    user = insert(:user)
+
+    {:ok, auth1} = Authorization.create_authorization(app1, user)
+    {:ok, auth2} = Authorization.create_authorization(app2, user)
+
+    {:ok, token1} = Token.exchange_token(app1, auth1)
+    {:ok, token2} = Token.exchange_token(app2, auth2)
+
+    {tokens, _} = Token.delete_user_tokens(user)
+
+    assert tokens == 2
+  end
 end