Groups: Add basic groups.
This commit is contained in:
parent
42e495df2b
commit
821b36f06c
74
lib/pleroma/group.ex
Normal file
74
lib/pleroma/group.ex
Normal file
@ -0,0 +1,74 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Group do
|
||||
use Ecto.Schema
|
||||
|
||||
import Ecto.Changeset
|
||||
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Web
|
||||
alias Pleroma.EctoType.ActivityPub.ObjectValidators
|
||||
|
||||
@moduledoc """
|
||||
Groups contain all the additional information about a group that's not stored
|
||||
in the user table.
|
||||
|
||||
Concepts:
|
||||
|
||||
- Groups have an owner
|
||||
- Groups have members, invited by the owner.
|
||||
"""
|
||||
|
||||
@type t :: %__MODULE__{}
|
||||
@primary_key {:id, FlakeId.Ecto.CompatType, autogenerate: true}
|
||||
|
||||
schema "groups" do
|
||||
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
||||
belongs_to(:owner, User, type: FlakeId.Ecto.CompatType, foreign_key: :owner_id)
|
||||
|
||||
field(:members, {:array, ObjectValidators.ObjectID})
|
||||
field(:name, :string)
|
||||
field(:description, :string)
|
||||
field(:members_collection, :string)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@spec create(map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
|
||||
def create(params) do
|
||||
with {:ok, user} <- generate_user() do
|
||||
%__MODULE__{user_id: user.id, members_collection: "#{user.ap_id}/members"}
|
||||
|> changeset(params)
|
||||
|> Repo.insert()
|
||||
end
|
||||
end
|
||||
|
||||
defp generate_ap_id(id) do
|
||||
"#{Web.base_url()}/groups/#{id}"
|
||||
end
|
||||
|
||||
defp generate_user() do
|
||||
id = Ecto.UUID.generate()
|
||||
ap_id = generate_ap_id(id)
|
||||
|
||||
%{
|
||||
ap_id: ap_id,
|
||||
name: id,
|
||||
nickname: id,
|
||||
follower_address: "#{ap_id}/followers",
|
||||
following_address: "#{ap_id}/following",
|
||||
local: true
|
||||
}
|
||||
|> User.group_changeset()
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
def changeset(struct, params) do
|
||||
struct
|
||||
|> cast(params, [:user_id, :owner_id, :name, :description, :members_collection])
|
||||
|> validate_required([:user_id, :owner_id, :members_collection])
|
||||
end
|
||||
end
|
@ -407,6 +407,12 @@ defmodule Pleroma.User do
|
||||
|
||||
defp fix_follower_address(params), do: params
|
||||
|
||||
def group_changeset(struct \\ %User{actor_type: "Group"}, params) do
|
||||
struct
|
||||
|> cast(params, [:ap_id, :nickname, :name, :follower_address, :following_address, :local])
|
||||
|> validate_required([:ap_id, :nickname, :name, :follower_address, :following_address, :local])
|
||||
end
|
||||
|
||||
def remote_user_changeset(struct \\ %User{local: false}, params) do
|
||||
bio_limit = Config.get([:instance, :user_bio_length], 5000)
|
||||
name_limit = Config.get([:instance, :user_name_length], 100)
|
||||
|
17
priv/repo/migrations/20210113150220_create_groups.exs
Normal file
17
priv/repo/migrations/20210113150220_create_groups.exs
Normal file
@ -0,0 +1,17 @@
|
||||
defmodule Pleroma.Repo.Migrations.CreateGroups do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:groups, primary_key: false) do
|
||||
add(:id, :uuid, primary_key: true)
|
||||
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all), null: false)
|
||||
add(:owner_id, references(:users, type: :uuid, on_delete: :nilify_all))
|
||||
add(:members, {:array, :string}, default: [])
|
||||
add(:name, :text)
|
||||
add(:description, :text)
|
||||
add(:members_collection, :text)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
end
|
||||
end
|
36
test/pleroma/group_test.exs
Normal file
36
test/pleroma/group_test.exs
Normal file
@ -0,0 +1,36 @@
|
||||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.GroupTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.Group
|
||||
alias Pleroma.Repo
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
test "a user can create a group" do
|
||||
user = insert(:user)
|
||||
{:ok, group} = Group.create(%{owner_id: user.id, name: "cofe", description: "corndog"})
|
||||
group = Repo.preload(group, :user)
|
||||
|
||||
assert group.user.actor_type == "Group"
|
||||
assert group.owner_id == user.id
|
||||
assert group.name == "cofe"
|
||||
assert group.description == "corndog"
|
||||
|
||||
# Deleting the owner does not delete the group, just orphans it
|
||||
Repo.delete(user)
|
||||
|
||||
group =
|
||||
Repo.get(Group, group.id)
|
||||
|> Repo.preload(:user)
|
||||
|
||||
assert group.owner_id == nil
|
||||
|
||||
# Deleting the group user deletes the group
|
||||
Repo.delete(group.user)
|
||||
refute Repo.get(Group, group.id)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user