mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
add bans
This commit is contained in:
parent
54fd5f3c47
commit
ab5b7782c7
7 changed files with 126 additions and 2 deletions
|
@ -293,4 +293,57 @@ defmodule Philomena.Bans do
|
||||||
def change_user(%User{} = user) do
|
def change_user(%User{} = user) do
|
||||||
User.changeset(user, %{})
|
User.changeset(user, %{})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Returns the first ban, if any, that matches the specified request
|
||||||
|
attributes.
|
||||||
|
"""
|
||||||
|
def exists_for?(user, ip, fingerprint) do
|
||||||
|
now = DateTime.utc_now()
|
||||||
|
queries =
|
||||||
|
subnet_query(ip, now) ++
|
||||||
|
fingerprint_query(fingerprint, now) ++
|
||||||
|
user_query(user, now)
|
||||||
|
|
||||||
|
union_all_queries(queries)
|
||||||
|
|> limit(1)
|
||||||
|
|> Repo.one()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp fingerprint_query(nil, _now), do: []
|
||||||
|
defp fingerprint_query(fingerprint, now) do
|
||||||
|
[
|
||||||
|
Fingerprint
|
||||||
|
|> select([:id, :reason, :valid_until])
|
||||||
|
|> where([f], f.enabled and f.valid_until > ^now)
|
||||||
|
|> where([f], f.fingerprint == ^fingerprint)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp subnet_query(nil, _now), do: []
|
||||||
|
defp subnet_query(ip, now) do
|
||||||
|
{:ok, inet} = EctoNetwork.INET.cast(ip)
|
||||||
|
|
||||||
|
[
|
||||||
|
Subnet
|
||||||
|
|> select([:id, :reason, :valid_until])
|
||||||
|
|> where([s], s.enabled and s.valid_until > ^now)
|
||||||
|
|> where(fragment("specification >>= ?", ^inet))
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp user_query(nil, _now), do: []
|
||||||
|
defp user_query(user, now) do
|
||||||
|
[
|
||||||
|
User
|
||||||
|
|> select([:id, :reason, :valid_until])
|
||||||
|
|> where([u], u.enabled and u.valid_until > ^now)
|
||||||
|
|> where([u], u.user_id == ^user.id)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp union_all_queries([query]),
|
||||||
|
do: query
|
||||||
|
defp union_all_queries([query | rest]),
|
||||||
|
do: query |> union_all(^union_all_queries(rest))
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,9 @@ defmodule PhilomenaWeb.Endpoint do
|
||||||
websocket: true,
|
websocket: true,
|
||||||
longpoll: false
|
longpoll: false
|
||||||
|
|
||||||
|
# Overwrite remote_ip based on X-Forwarded-For
|
||||||
|
plug RemoteIp
|
||||||
|
|
||||||
# Serve at "/" the static files from "priv/static" directory.
|
# Serve at "/" the static files from "priv/static" directory.
|
||||||
#
|
#
|
||||||
# You should set gzip to true if you are running phx.digest
|
# You should set gzip to true if you are running phx.digest
|
||||||
|
@ -48,6 +51,6 @@ defmodule PhilomenaWeb.Endpoint do
|
||||||
|
|
||||||
plug PhilomenaWeb.Plugs.ReloadUser
|
plug PhilomenaWeb.Plugs.ReloadUser
|
||||||
plug PhilomenaWeb.Plugs.RenderTime
|
plug PhilomenaWeb.Plugs.RenderTime
|
||||||
plug PhilomenaWeb.Plugs.CurrentFilter
|
plug PhilomenaWeb.Plugs.Referrer
|
||||||
plug PhilomenaWeb.Router
|
plug PhilomenaWeb.Router
|
||||||
end
|
end
|
||||||
|
|
32
lib/philomena_web/plugs/current_ban.ex
Normal file
32
lib/philomena_web/plugs/current_ban.ex
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
defmodule PhilomenaWeb.Plugs.CurrentBan do
|
||||||
|
@moduledoc """
|
||||||
|
This plug loads the ban for the current user.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
plug PhilomenaWeb.Plugs.Ban
|
||||||
|
"""
|
||||||
|
alias Philomena.Bans
|
||||||
|
alias Plug.Conn
|
||||||
|
alias Pow.Plug
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
@spec init(any()) :: any()
|
||||||
|
def init(opts), do: opts
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
@spec call(Conn.t(), any()) :: Conn.t()
|
||||||
|
def call(conn, _opts) do
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> Conn.fetch_cookies()
|
||||||
|
|
||||||
|
fingerprint = conn.cookies["_ses"]
|
||||||
|
user = Plug.current_user(conn)
|
||||||
|
ip = conn.remote_ip
|
||||||
|
|
||||||
|
ban = Bans.exists_for?(user, ip, fingerprint)
|
||||||
|
|
||||||
|
Conn.assign(conn, :current_ban, ban)
|
||||||
|
end
|
||||||
|
end
|
30
lib/philomena_web/plugs/referrer.ex
Normal file
30
lib/philomena_web/plugs/referrer.ex
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
defmodule PhilomenaWeb.Plugs.Referrer do
|
||||||
|
@moduledoc """
|
||||||
|
This plug assigns the HTTP Referer, if it exists. Note the misspelling
|
||||||
|
in the standard.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
plug PhilomenaWeb.Plugs.Referrer
|
||||||
|
"""
|
||||||
|
|
||||||
|
alias Plug.Conn
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
@spec init(any()) :: any()
|
||||||
|
def init(opts), do: opts
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
@spec call(Conn.t(), any()) :: Conn.t()
|
||||||
|
def call(conn, _opts) do
|
||||||
|
case Conn.get_req_header(conn, "referer") do
|
||||||
|
[] ->
|
||||||
|
conn
|
||||||
|
|> Conn.assign(:referrer, "/")
|
||||||
|
|
||||||
|
[referrer] ->
|
||||||
|
conn
|
||||||
|
|> Conn.assign(:referrer, referrer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,9 +9,11 @@ defmodule PhilomenaWeb.Router do
|
||||||
plug :fetch_flash
|
plug :fetch_flash
|
||||||
plug :protect_from_forgery
|
plug :protect_from_forgery
|
||||||
plug :put_secure_browser_headers
|
plug :put_secure_browser_headers
|
||||||
|
plug PhilomenaWeb.Plugs.CurrentFilter
|
||||||
plug PhilomenaWeb.Plugs.ImageFilter
|
plug PhilomenaWeb.Plugs.ImageFilter
|
||||||
plug PhilomenaWeb.Plugs.Pagination
|
plug PhilomenaWeb.Plugs.Pagination
|
||||||
plug PhilomenaWeb.Plugs.EnsureUserEnabledPlug
|
plug PhilomenaWeb.Plugs.EnsureUserEnabledPlug
|
||||||
|
plug PhilomenaWeb.Plugs.CurrentBan
|
||||||
end
|
end
|
||||||
|
|
||||||
pipeline :api do
|
pipeline :api do
|
||||||
|
|
3
mix.exs
3
mix.exs
|
@ -57,7 +57,8 @@ defmodule Philomena.MixProject do
|
||||||
{:qrcode, "~> 0.1.5"},
|
{:qrcode, "~> 0.1.5"},
|
||||||
{:redix, "~> 0.10.2"},
|
{:redix, "~> 0.10.2"},
|
||||||
{:bamboo, "~> 1.2"},
|
{:bamboo, "~> 1.2"},
|
||||||
{:bamboo_smtp, "~> 1.7"}
|
{:bamboo_smtp, "~> 1.7"},
|
||||||
|
{:remote_ip, "~> 0.1.5"}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
3
mix.lock
3
mix.lock
|
@ -5,6 +5,7 @@
|
||||||
"canada": {:hex, :canada, "1.0.2", "040e4c47609b0a67d5773ac1fbe5e99f840cef173d69b739beda7c98453e0770", [:mix], [], "hexpm"},
|
"canada": {:hex, :canada, "1.0.2", "040e4c47609b0a67d5773ac1fbe5e99f840cef173d69b739beda7c98453e0770", [:mix], [], "hexpm"},
|
||||||
"canary": {:hex, :canary, "1.1.1", "4138d5e05db8497c477e4af73902eb9ae06e49dceaa13c2dd9f0b55525ded48b", [:mix], [{:canada, "~> 1.0.1", [hex: :canada, repo: "hexpm", optional: false]}, {:ecto, ">= 1.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
"canary": {:hex, :canary, "1.1.1", "4138d5e05db8497c477e4af73902eb9ae06e49dceaa13c2dd9f0b55525ded48b", [:mix], [{:canada, "~> 1.0.1", [hex: :canada, repo: "hexpm", optional: false]}, {:ecto, ">= 1.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
"certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
|
||||||
"comeonin": {:hex, :comeonin, "5.1.2", "fbbbbbfcf0f0e9900c0336d16c8d462edf838ba1759577e29cc5fbd7c28a4540", [:mix], [], "hexpm"},
|
"comeonin": {:hex, :comeonin, "5.1.2", "fbbbbbfcf0f0e9900c0336d16c8d462edf838ba1759577e29cc5fbd7c28a4540", [:mix], [], "hexpm"},
|
||||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
||||||
"cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
|
"cowboy": {:hex, :cowboy, "2.7.0", "91ed100138a764355f43316b1d23d7ff6bdb0de4ea618cb5d8677c93a7a2f115", [:rebar3], [{:cowlib, "~> 2.8.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
"hackney": {:hex, :hackney, "1.15.2", "07e33c794f8f8964ee86cebec1a8ed88db5070e52e904b8f12209773c1036085", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.5", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"httpoison": {:hex, :httpoison, "1.6.0", "0a148c836e8e5fbec82c3cea37465a603bd42e314b73a8448ad50020757a00bd", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
"httpoison": {:hex, :httpoison, "1.6.0", "0a148c836e8e5fbec82c3cea37465a603bd42e314b73a8448ad50020757a00bd", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm"},
|
||||||
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||||
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
|
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
|
||||||
|
@ -47,6 +49,7 @@
|
||||||
"qrcode": {:hex, :qrcode, "0.1.5", "551271830515c150f34568345b060c625deb0e6691db2a01b0a6de3aafc93886", [:mix], [], "hexpm"},
|
"qrcode": {:hex, :qrcode, "0.1.5", "551271830515c150f34568345b060c625deb0e6691db2a01b0a6de3aafc93886", [:mix], [], "hexpm"},
|
||||||
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
|
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"},
|
||||||
"redix": {:hex, :redix, "0.10.2", "a9eabf47898aa878650df36194aeb63966d74f5bd69d9caa37babb32dbb93c5d", [:mix], [{:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
|
"redix": {:hex, :redix, "0.10.2", "a9eabf47898aa878650df36194aeb63966d74f5bd69d9caa37babb32dbb93c5d", [:mix], [{:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"remote_ip": {:hex, :remote_ip, "0.1.5", "0d8eb8a80387e196b0f48b3e7efb75525d1097cdb0ec70a4c69dd2ce9237c16c", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:inet_cidr, "~> 1.0", [hex: :inet_cidr, repo: "hexpm", optional: false]}, {:plug, "~> 1.2", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"retry": {:hex, :retry, "0.13.0", "bb9b2713f70f39337837852337ad280c77662574f4fb852a8386c269f3d734c4", [:mix], [], "hexpm"},
|
"retry": {:hex, :retry, "0.13.0", "bb9b2713f70f39337837852337ad280c77662574f4fb852a8386c269f3d734c4", [:mix], [], "hexpm"},
|
||||||
"scrivener": {:hex, :scrivener, "2.7.0", "fa94cdea21fad0649921d8066b1833d18d296217bfdf4a5389a2f45ee857b773", [:mix], [], "hexpm"},
|
"scrivener": {:hex, :scrivener, "2.7.0", "fa94cdea21fad0649921d8066b1833d18d296217bfdf4a5389a2f45ee857b773", [:mix], [], "hexpm"},
|
||||||
"scrivener_ecto": {:hex, :scrivener_ecto, "2.2.0", "53d5f1ba28f35f17891cf526ee102f8f225b7024d1cdaf8984875467158c9c5e", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:scrivener, "~> 2.4", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm"},
|
"scrivener_ecto": {:hex, :scrivener_ecto, "2.2.0", "53d5f1ba28f35f17891cf526ee102f8f225b7024d1cdaf8984875467158c9c5e", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:scrivener, "~> 2.4", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
|
Loading…
Reference in a new issue