staff tools for ips

This commit is contained in:
byte[] 2019-12-07 20:49:28 -05:00
parent c8e63adc22
commit 0d48fc59b2
13 changed files with 202 additions and 15 deletions

View file

@ -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

View file

@ -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})

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,3 @@
defmodule PhilomenaWeb.FingerprintProfileView do
use PhilomenaWeb, :view
end

View file

@ -0,0 +1,3 @@
defmodule PhilomenaWeb.IpProfileView do
use PhilomenaWeb, :view
end