1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# 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.UserRelationship
@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)
has_many(:members, through: [:user, :group_members])
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
def is_member?(%{user_id: user_id}, member) do
UserRelationship.membership_exists?(%User{id: user_id}, member)
end
def members(group) do
Repo.preload(group, :members).members
end
def add_member(%{user_id: user_id} = group, member) do
with {:ok, _relationship} <- UserRelationship.create_membership(%User{id: user_id}, member) do
{:ok, group}
end
end
def remove_member(%{user_id: user_id} = group, member) do
with {:ok, _relationship} <- UserRelationship.delete_membership(%User{id: user_id}, member) do
{:ok, group}
end
end
end
|