Add follower_address to users, add on generation.
authorRoger Braun <roger@rogerbraun.net>
Wed, 19 Jul 2017 16:49:25 +0000 (18:49 +0200)
committerRoger Braun <roger@rogerbraun.net>
Wed, 19 Jul 2017 16:49:25 +0000 (18:49 +0200)
lib/pleroma/user.ex
priv/repo/migrations/20170719152213_add_follower_address_to_user.exs [new file with mode: 0644]
test/support/factory.ex
test/user_test.exs

index a30c8daed35aceb665cbbe7de22c2eea6d112f55..af0e569a49f2280f51df92ac8d2899146eb4765f 100644 (file)
@@ -21,6 +21,7 @@ defmodule Pleroma.User do
     field :avatar, :map
     field :local, :boolean, default: true
     field :info, :map, default: %{}
+    field :follower_address, :string
 
     timestamps()
   end
@@ -58,7 +59,7 @@ defmodule Pleroma.User do
       select: count(a.id)
 
     follower_count_query = from u in User,
-      where: fragment("? @> ?", u.following, ^User.ap_followers(user)),
+      where: fragment("? @> ?", u.following, ^user.follower_address),
       select: count(u.id)
 
     %{
@@ -70,7 +71,7 @@ defmodule Pleroma.User do
 
   @email_regex ~r/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
   def remote_user_creation(params) do
-    %User{}
+    changes = %User{}
     |> cast(params, [:bio, :name, :ap_id, :nickname, :info, :avatar])
     |> validate_required([:name, :ap_id, :nickname])
     |> unique_constraint(:nickname)
@@ -78,6 +79,13 @@ defmodule Pleroma.User do
     |> validate_length(:bio, max: 5000)
     |> validate_length(:name, max: 100)
     |> put_change(:local, false)
+    if changes.valid? do
+      followers = User.ap_followers(%User{nickname: changes.changes[:nickname]})
+      changes
+      |> put_change(:follower_address, followers)
+    else
+      changes
+    end
   end
 
   def register_changeset(struct, params \\ %{}) do
@@ -100,13 +108,14 @@ defmodule Pleroma.User do
       |> put_change(:password_hash, hashed)
       |> put_change(:ap_id, ap_id)
       |> put_change(:following, [followers])
+      |> put_change(:follower_address, followers)
     else
       changeset
     end
   end
 
   def follow(%User{} = follower, %User{} = followed) do
-    ap_followers = User.ap_followers(followed)
+    ap_followers = followed.follower_address
     if following?(follower, followed) do
       {:error,
        "Could not follow user: #{followed.nickname} is already on your list."}
@@ -125,7 +134,7 @@ defmodule Pleroma.User do
   end
 
   def unfollow(%User{} = follower, %User{} = followed) do
-    ap_followers = User.ap_followers(followed)
+    ap_followers = followed.follower_address
     if following?(follower, followed) do
       following = follower.following
       |> List.delete(ap_followers)
@@ -140,7 +149,7 @@ defmodule Pleroma.User do
   end
 
   def following?(%User{} = follower, %User{} = followed) do
-    Enum.member?(follower.following, User.ap_followers(followed))
+    Enum.member?(follower.following, followed.follower_address)
   end
 
   def get_by_ap_id(ap_id) do
diff --git a/priv/repo/migrations/20170719152213_add_follower_address_to_user.exs b/priv/repo/migrations/20170719152213_add_follower_address_to_user.exs
new file mode 100644 (file)
index 0000000..bd3c93b
--- /dev/null
@@ -0,0 +1,33 @@
+defmodule Pleroma.Repo.Migrations.AddFollowerAddressToUser do
+  use Ecto.Migration
+  import Ecto.Query
+  import Supervisor.Spec
+  alias Pleroma.{Repo, User}
+
+  def up do
+    alter table(:users) do
+      add :follower_address, :string, unique: true
+    end
+    flush()
+
+    children = [
+      # Start the endpoint when the application starts
+      supervisor(Pleroma.Web.Endpoint, [])
+    ]
+    opts = [strategy: :one_for_one, name: Pleroma.Supervisor]
+    Supervisor.start_link(children, opts)
+
+    Enum.each(Repo.all(User), fn (user) ->
+      if !user.follower_address do
+        cs = Ecto.Changeset.change(user, %{follower_address: User.ap_followers(user)})
+        Repo.update!(cs)
+      end
+    end)
+  end
+
+  def down do
+    alter table(:users) do
+      remove :follower_address
+    end
+  end
+end
index bb3bdb02c8adc4d6353c48e9a6aa2ead88c89486..1356ebde9a82093728c0133344e545f9afe603e6 100644 (file)
@@ -9,7 +9,7 @@ defmodule Pleroma.Factory do
       password_hash: Comeonin.Pbkdf2.hashpwsalt("test"),
       bio: sequence(:bio, &"Tester Number #{&1}"),
     }
-    %{ user | ap_id: Pleroma.User.ap_id(user) }
+    %{ user | ap_id: Pleroma.User.ap_id(user), follower_address: Pleroma.User.ap_followers(user) }
   end
 
   def note_factory do
index c79564385f261a0114435d60fd8d991d868abd86..0f42e9b513495c8047935d14a90ed7d6d82b3640 100644 (file)
@@ -103,6 +103,7 @@ defmodule Pleroma.UserTest do
       assert is_binary(changeset.changes[:password_hash])
       assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
       assert changeset.changes[:following] == [User.ap_followers(%User{nickname: @full_user_data.nickname})]
+      assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
     end
   end
 
@@ -162,6 +163,12 @@ defmodule Pleroma.UserTest do
       assert cs.valid?
     end
 
+    test "it sets the follower_adress" do
+      cs = User.remote_user_creation(@valid_remote)
+      # remote users get a fake local follower address
+      assert cs.changes.follower_address == User.ap_followers(%User{ nickname: @valid_remote[:nickname] })
+    end
+
     test "it enforces the fqn format for nicknames" do
       cs = User.remote_user_creation(%{@valid_remote | nickname: "bla"})
       assert cs.changes.local == false