mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
staff tools for ips
This commit is contained in:
parent
c8e63adc22
commit
0d48fc59b2
13 changed files with 202 additions and 15 deletions
|
@ -177,7 +177,7 @@ defmodule Philomena.Users do
|
||||||
|
|
||||||
defp setup_roles(nil), do: nil
|
defp setup_roles(nil), do: nil
|
||||||
defp setup_roles(user) do
|
defp setup_roles(user) do
|
||||||
role_map = Map.new(user.roles, &{&1.name, &1.resource_type || true})
|
role_map = Map.new(user.roles, &{&1.resource_type || &1.name, &1.name})
|
||||||
|
|
||||||
%{user | role_map: role_map}
|
%{user | role_map: role_map}
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
||||||
alias Philomena.Comments.Comment
|
alias Philomena.Comments.Comment
|
||||||
alias Philomena.Commissions.Commission
|
alias Philomena.Commissions.Commission
|
||||||
alias Philomena.Conversations.Conversation
|
alias Philomena.Conversations.Conversation
|
||||||
|
alias Philomena.DuplicateReports.DuplicateReport
|
||||||
alias Philomena.Images.Image
|
alias Philomena.Images.Image
|
||||||
alias Philomena.Forums.Forum
|
alias Philomena.Forums.Forum
|
||||||
alias Philomena.Topics.Topic
|
alias Philomena.Topics.Topic
|
||||||
|
@ -11,6 +12,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
||||||
alias Philomena.Galleries.Gallery
|
alias Philomena.Galleries.Gallery
|
||||||
alias Philomena.DnpEntries.DnpEntry
|
alias Philomena.DnpEntries.DnpEntry
|
||||||
alias Philomena.UserLinks.UserLink
|
alias Philomena.UserLinks.UserLink
|
||||||
|
alias Philomena.Tags.Tag
|
||||||
|
|
||||||
# Admins can do anything
|
# Admins can do anything
|
||||||
def can?(%User{role: "admin"}, _action, _model), do: true
|
def can?(%User{role: "admin"}, _action, _model), do: true
|
||||||
|
@ -36,12 +38,43 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
|
||||||
# View conversations
|
# View conversations
|
||||||
def can?(%User{role: "moderator"}, :show, %Conversation{}), do: true
|
def can?(%User{role: "moderator"}, :show, %Conversation{}), do: true
|
||||||
|
|
||||||
|
# View IP addresses and fingerprints
|
||||||
|
def can?(%User{role: "moderator"}, :show, :ip_address), do: true
|
||||||
|
|
||||||
#
|
#
|
||||||
# Assistants can...
|
# Assistants can...
|
||||||
#
|
#
|
||||||
|
|
||||||
# View images
|
|
||||||
def can?(%User{role: "assistant"}, :show, %Image{}), do: true
|
# Image assistant actions
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Image" => "moderator"}}, :show, %Image{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Image" => "moderator"}}, :hide, %Image{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Image" => "moderator"}}, :edit, %Image{}), do: true
|
||||||
|
|
||||||
|
# Dupe assistant actions
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"DuplicateReport" => "moderator"}}, :edit, %DuplicateReport{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"DuplicateReport" => "moderator"}}, :show, %Image{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"DuplicateReport" => "moderator"}}, :edit, %Image{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"DuplicateReport" => "moderator"}}, :hide, %Comment{}), do: true
|
||||||
|
|
||||||
|
# Comment assistant actions
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Comment" => "moderator"}}, :show, %Comment{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Comment" => "moderator"}}, :edit, %Comment{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Comment" => "moderator"}}, :hide, %Comment{}), do: true
|
||||||
|
|
||||||
|
# Topic assistant actions
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Topic" => "moderator"}}, :show, %Topic{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Topic" => "moderator"}}, :edit, %Topic{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Topic" => "moderator"}}, :show, %Post{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Topic" => "moderator"}}, :edit, %Post{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Topic" => "moderator"}}, :hide, %Post{}), do: true
|
||||||
|
|
||||||
|
# Tag assistant actions
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"Tag" => "moderator"}}, :edit, %Tag{}), do: true
|
||||||
|
|
||||||
|
# User link assistant actions
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"UserLink" => "moderator"}}, :show, %UserLink{}), do: true
|
||||||
|
def can?(%User{role: "assistant", role_map: %{"UserLink" => "moderator"}}, :edit, %UserLink{}), do: true
|
||||||
|
|
||||||
# View forums
|
# View forums
|
||||||
def can?(%User{role: "assistant"}, :show, %Forum{access_level: level})
|
def can?(%User{role: "assistant"}, :show, %Forum{access_level: level})
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
defmodule PhilomenaWeb.FingerprintProfileController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.UserFingerprints.UserFingerprint
|
||||||
|
alias Philomena.Bans.Fingerprint
|
||||||
|
alias Philomena.Repo
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
plug :authorize_ip
|
||||||
|
|
||||||
|
def show(conn, %{"id" => fingerprint}) do
|
||||||
|
user_fps =
|
||||||
|
UserFingerprint
|
||||||
|
|> where(fingerprint: ^fingerprint)
|
||||||
|
|> order_by(desc: :updated_at)
|
||||||
|
|> preload(:user)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
fp_bans =
|
||||||
|
Fingerprint
|
||||||
|
|> where(fingerprint: ^fingerprint)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
render(conn, "show.html", fingerprint: fingerprint, user_fps: user_fps, fp_bans: fp_bans)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp authorize_ip(conn, _opts) do
|
||||||
|
case Canada.Can.can?(conn.assigns.current_user, :show, :ip_address) do
|
||||||
|
false -> PhilomenaWeb.NotAuthorizedPlug.call(conn)
|
||||||
|
true -> conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
35
lib/philomena_web/controllers/ip_profile_controller.ex
Normal file
35
lib/philomena_web/controllers/ip_profile_controller.ex
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
defmodule PhilomenaWeb.IpProfileController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.UserIps.UserIp
|
||||||
|
alias Philomena.Bans.Subnet
|
||||||
|
alias Philomena.Repo
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
plug :authorize_ip
|
||||||
|
|
||||||
|
def show(conn, %{"id" => ip}) do
|
||||||
|
{:ok, ip} = EctoNetwork.INET.cast(ip)
|
||||||
|
|
||||||
|
user_ips =
|
||||||
|
UserIp
|
||||||
|
|> where(ip: ^ip)
|
||||||
|
|> order_by(desc: :updated_at)
|
||||||
|
|> preload(:user)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
subnet_bans =
|
||||||
|
Subnet
|
||||||
|
|> where([s], fragment("? >>= ?", s.specification, ^ip))
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
render(conn, "show.html", ip: ip, user_ips: user_ips, subnet_bans: subnet_bans)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp authorize_ip(conn, _opts) do
|
||||||
|
case Canada.Can.can?(conn.assigns.current_user, :show, :ip_address) do
|
||||||
|
false -> PhilomenaWeb.NotAuthorizedPlug.call(conn)
|
||||||
|
true -> conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -151,6 +151,9 @@ defmodule PhilomenaWeb.Router do
|
||||||
resources "/read", Channel.ReadController, only: [:create], singleton: true
|
resources "/read", Channel.ReadController, only: [:create], singleton: true
|
||||||
resources "/subscription", Channel.SubscriptionController, only: [:create, :delete], singleton: true
|
resources "/subscription", Channel.SubscriptionController, only: [:create, :delete], singleton: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources "/ip_profiles", IpProfileController, only: [:show]
|
||||||
|
resources "/fingerprint_profiles", FingerprintProfileController, only: [:show]
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", PhilomenaWeb do
|
scope "/", PhilomenaWeb do
|
||||||
|
|
|
@ -24,9 +24,9 @@ article.block.communication id="comment_#{@comment.id}"
|
||||||
=<> "Delete"
|
=<> "Delete"
|
||||||
= if can?(@conn, :manage, @comment) do
|
= if can?(@conn, :manage, @comment) do
|
||||||
.communication__info
|
.communication__info
|
||||||
=<> link_to_ip(@comment.ip)
|
=<> link_to_ip(@conn, @comment.ip)
|
||||||
.communication__info
|
.communication__info
|
||||||
=<> link_to_fingerprint(@comment.fingerprint)
|
=<> link_to_fingerprint(@conn, @comment.fingerprint)
|
||||||
/- if can?(:hide, Comment)
|
/- if can?(:hide, Comment)
|
||||||
/ .js-staff-action
|
/ .js-staff-action
|
||||||
/ - if !comment.hidden_from_users && !comment.destroyed_content
|
/ - if !comment.hidden_from_users && !comment.destroyed_content
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
h1
|
||||||
|
= @fingerprint
|
||||||
|
' 's fingerprint profile
|
||||||
|
|
||||||
|
ul
|
||||||
|
li = link "View images this fingerprint has uploaded", to: Routes.search_path(@conn, :index, q: "fingerprint:#{@fingerprint}")
|
||||||
|
li = link "View comments this fingerprint has posted", to: Routes.comment_path(@conn, :index, cq: "fingerprint:#{@fingerprint}")
|
||||||
|
li = link "View posts this fingerprint has made", to: Routes.post_path(@conn, :index, pq: "fingerprint:#{@fingerprint}")
|
||||||
|
|
||||||
|
/= render partial: "bans/ban_list", locals: { bans: @bans }
|
||||||
|
|
||||||
|
h2 Administration Options
|
||||||
|
/ul
|
||||||
|
li = link "View tag changes", "/fingerprint_profiles/#{@fingerprint}/tag_changes"
|
||||||
|
li = link "View source URL history", "/fingerprint_profiles/#{@fingerprint}/source_changes"
|
||||||
|
li = link "View reports this fingerprint has made", admin_reports_path(rq: "ip:#{@fingerprint}")
|
||||||
|
li = link "View fingerprint ban history", admin_subnet_bans_path(q: @fingerprint)
|
||||||
|
li = link "Ban this sucker", new_admin_subnet_ban_path(fingerprint: @fingerprint)
|
||||||
|
|
||||||
|
h4 Observed users
|
||||||
|
table.table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th Username
|
||||||
|
th Account Used
|
||||||
|
th Last Seen
|
||||||
|
th Created At
|
||||||
|
tbody
|
||||||
|
= for ufp <- @user_fps do
|
||||||
|
tr
|
||||||
|
td
|
||||||
|
= link ufp.user.name, to: Routes.profile_path(@conn, :show, ufp.user)
|
||||||
|
td
|
||||||
|
=> ufp.uses
|
||||||
|
' times
|
||||||
|
td
|
||||||
|
=> pretty_time ufp.updated_at
|
||||||
|
td
|
||||||
|
=> pretty_time ufp.user.created_at
|
|
@ -55,8 +55,8 @@
|
||||||
' by
|
' by
|
||||||
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image, awards: true, conn: @conn
|
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image, awards: true, conn: @conn
|
||||||
= if can?(@conn, :manage, @image) do
|
= if can?(@conn, :manage, @image) do
|
||||||
=<> link_to_ip(@image.ip)
|
=> link_to_ip(@conn, @image.ip)
|
||||||
=<> link_to_fingerprint(@image.fingerprint)
|
=> link_to_fingerprint(@conn, @image.fingerprint)
|
||||||
a href="#"
|
a href="#"
|
||||||
i.fa.fa-edit
|
i.fa.fa-edit
|
||||||
span.image-size
|
span.image-size
|
||||||
|
|
39
lib/philomena_web/templates/ip_profile/show.html.slime
Normal file
39
lib/philomena_web/templates/ip_profile/show.html.slime
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
h1
|
||||||
|
= @ip
|
||||||
|
' 's IP profile
|
||||||
|
|
||||||
|
ul
|
||||||
|
li = link "View images this IP has uploaded", to: Routes.search_path(@conn, :index, q: "ip:#{@ip}")
|
||||||
|
li = link "View comments this IP has posted", to: Routes.comment_path(@conn, :index, cq: "ip:#{@ip}")
|
||||||
|
li = link "View posts this IP has made", to: Routes.post_path(@conn, :index, pq: "ip:#{@ip}")
|
||||||
|
|
||||||
|
/= render partial: "bans/ban_list", locals: { bans: @bans }
|
||||||
|
|
||||||
|
h2 Administration Options
|
||||||
|
/ul
|
||||||
|
li = link "View tag changes", "/ip_profiles/#{@ip}/tag_changes"
|
||||||
|
li = link "View source URL history", "/ip_profiles/#{@ip}/source_changes"
|
||||||
|
li = link "View reports this IP has made", admin_reports_path(rq: "ip:#{@ip}")
|
||||||
|
li = link "View IP ban history", admin_subnet_bans_path(q: @ip)
|
||||||
|
li = link "Ban this sucker", new_admin_subnet_ban_path(ip: @ip)
|
||||||
|
|
||||||
|
h4 Observed users
|
||||||
|
table.table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th Username
|
||||||
|
th Account Used
|
||||||
|
th Last Seen
|
||||||
|
th Created At
|
||||||
|
tbody
|
||||||
|
= for uip <- @user_ips do
|
||||||
|
tr
|
||||||
|
td
|
||||||
|
= link uip.user.name, to: Routes.profile_path(@conn, :show, uip.user)
|
||||||
|
td
|
||||||
|
=> uip.uses
|
||||||
|
' times
|
||||||
|
td
|
||||||
|
=> pretty_time uip.updated_at
|
||||||
|
td
|
||||||
|
=> pretty_time uip.user.created_at
|
|
@ -23,9 +23,9 @@ article.block.communication id="post_#{@post.id}"
|
||||||
=<> "Delete"
|
=<> "Delete"
|
||||||
= if can?(@conn, :manage, @post) do
|
= if can?(@conn, :manage, @post) do
|
||||||
.communication__info
|
.communication__info
|
||||||
=<> link_to_ip(@post.ip)
|
=<> link_to_ip(@conn, @post.ip)
|
||||||
.communication__info
|
.communication__info
|
||||||
=<> link_to_fingerprint(@post.fingerprint)
|
=<> link_to_fingerprint(@conn, @post.fingerprint)
|
||||||
/- if can?(:hide, Post)
|
/- if can?(:hide, Post)
|
||||||
/ .js-staff-action
|
/ .js-staff-action
|
||||||
/ - if !post.hidden_from_users && !post.destroyed_content
|
/ - if !post.hidden_from_users && !post.destroyed_content
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
defmodule PhilomenaWeb.AppView do
|
defmodule PhilomenaWeb.AppView do
|
||||||
|
alias PhilomenaWeb.Router.Helpers, as: Routes
|
||||||
use Phoenix.HTML
|
use Phoenix.HTML
|
||||||
|
|
||||||
@time_strings %{
|
@time_strings %{
|
||||||
|
@ -117,14 +118,12 @@ defmodule PhilomenaWeb.AppView do
|
||||||
defp text_or_na(nil), do: "N/A"
|
defp text_or_na(nil), do: "N/A"
|
||||||
defp text_or_na(text), do: text
|
defp text_or_na(text), do: text
|
||||||
|
|
||||||
# todo: make ip a real link
|
def link_to_ip(conn, ip) do
|
||||||
def link_to_ip(ip) do
|
link(text_or_na(ip), to: Routes.ip_profile_path(conn, :show, to_string(ip)))
|
||||||
link(text_or_na(ip), to: "#")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# todo: make fp a real link
|
def link_to_fingerprint(conn, fp) do
|
||||||
def link_to_fingerprint(fp) do
|
link(String.slice(text_or_na(fp), 0..6), to: Routes.fingerprint_profile_path(conn, :show, fp))
|
||||||
link(String.slice(text_or_na(fp), 0..6), to: "#")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def blank?(nil), do: true
|
def blank?(nil), do: true
|
||||||
|
|
3
lib/philomena_web/views/fingerprint_profile_view.ex
Normal file
3
lib/philomena_web/views/fingerprint_profile_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
defmodule PhilomenaWeb.FingerprintProfileView do
|
||||||
|
use PhilomenaWeb, :view
|
||||||
|
end
|
3
lib/philomena_web/views/ip_profile_view.ex
Normal file
3
lib/philomena_web/views/ip_profile_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
defmodule PhilomenaWeb.IpProfileView do
|
||||||
|
use PhilomenaWeb, :view
|
||||||
|
end
|
Loading…
Reference in a new issue