Merge branch 'develop' of ssh.gitgud.io:lambadalambda/pleroma into feature/unfollow-by-screen-name

This commit is contained in:
dtluna 2017-04-16 17:13:42 +03:00
commit f6547f7b7f
22 changed files with 145 additions and 49 deletions

View file

@ -18,6 +18,31 @@ defmodule Pleroma.Upload do
} }
end end
def store(%{"img" => "data:image/" <> image_data}) do
parsed = Regex.named_captures(~r/(?<filetype>jpeg|png|gif);base64,(?<data>.*)/, image_data)
data = Base.decode64!(parsed["data"])
uuid = Ecto.UUID.generate
upload_folder = Path.join(upload_path(), uuid)
File.mkdir_p!(upload_folder)
filename = Base.encode16(:crypto.hash(:sha256, data)) <> ".#{parsed["filetype"]}"
result_file = Path.join(upload_folder, filename)
File.write!(result_file, data)
content_type = "image/#{parsed["filetype"]}"
%{
"type" => "Image",
"url" => [%{
"type" => "Link",
"mediaType" => content_type,
"href" => url_for(Path.join(uuid, filename))
}],
"name" => filename,
"uuid" => uuid
}
end
defp upload_path do defp upload_path do
Application.get_env(:pleroma, Pleroma.Upload) Application.get_env(:pleroma, Pleroma.Upload)
|> Keyword.fetch!(:uploads) |> Keyword.fetch!(:uploads)

View file

@ -13,6 +13,7 @@ defmodule Pleroma.User do
field :password_confirmation, :string, virtual: true field :password_confirmation, :string, virtual: true
field :following, { :array, :string }, default: [] field :following, { :array, :string }, default: []
field :ap_id, :string field :ap_id, :string
field :avatar, :map
timestamps() timestamps()
end end

View file

@ -167,7 +167,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
Repo.all(query) Repo.all(query)
end end
def upload(%Plug.Upload{} = file) do def upload(file) do
data = Upload.store(file) data = Upload.store(file)
Repo.insert(%Object{data: data}) Repo.insert(%Object{data: data})
end end

View file

@ -45,5 +45,6 @@ defmodule Pleroma.Web.Router do
post "/favorites/create", TwitterAPI.Controller, :favorite post "/favorites/create", TwitterAPI.Controller, :favorite
post "/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite post "/favorites/destroy/:id", TwitterAPI.Controller, :unfavorite
post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet post "/statuses/retweet/:id", TwitterAPI.Controller, :retweet
post "/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar
end end
end end

View file

@ -4,8 +4,10 @@ defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenter do
alias Pleroma.User alias Pleroma.User
def to_map(user, opts) do def to_map(user, opts) do
image = case user.avatar do
image = "https://placehold.it/48x48" %{"url" => [%{"href" => href} | _]} -> href
_ -> "https://placehold.it/48x48"
end
following = if opts[:for] do following = if opts[:for] do
User.following?(opts[:for], user) User.following?(opts[:for], user)

View file

@ -3,6 +3,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
alias Pleroma.Web.TwitterAPI.TwitterAPI alias Pleroma.Web.TwitterAPI.TwitterAPI
alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter} alias Pleroma.Web.TwitterAPI.Representers.{UserRepresenter, ActivityRepresenter}
alias Pleroma.{Repo, Activity} alias Pleroma.{Repo, Activity}
alias Pleroma.Web.ActivityPub.ActivityPub
def verify_credentials(%{assigns: %{user: user}} = conn, _params) do def verify_credentials(%{assigns: %{user: user}} = conn, _params) do
response = user |> UserRepresenter.to_json(%{for: user}) response = user |> UserRepresenter.to_json(%{for: user})
@ -142,6 +143,18 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
end end
end end
def update_avatar(%{assigns: %{user: user}} = conn, params) do
{:ok, object} = ActivityPub.upload(params)
change = Ecto.Changeset.change(user, %{avatar: object.data})
{:ok, user} = Repo.update(change)
response = UserRepresenter.to_map(user, %{for: user})
|> Poison.encode!
conn
|> json_reply(200, response)
end
defp json_reply(conn, status, json) do defp json_reply(conn, status, json) do
conn conn
|> put_resp_content_type("application/json") |> put_resp_content_type("application/json")

View file

@ -0,0 +1,9 @@
defmodule Pleroma.Repo.Migrations.AddAvatarObjectToUsers do
use Ecto.Migration
def change do
alter table(:users) do
add :avatar, :map
end
end
end

View file

@ -1 +1 @@
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.a86c13eb46180b1b975a1acd59b52cc6.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.da7ea91e505330123f38.js></script><script type=text/javascript src=/static/js/vendor.d7d8813599feb765b152.js></script><script type=text/javascript src=/static/js/app.dcc60205ebdef9eb3d87.js></script></body></html> <!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.a86c13eb46180b1b975a1acd59b52cc6.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.66d994092e61600982a8.js></script><script type=text/javascript src=/static/js/vendor.d7d8813599feb765b152.js></script><script type=text/javascript src=/static/js/app.d4e0a640b375c4b52997.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
!function(e){function t(n){if(r[n])return r[n].exports;var a=r[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n=window.webpackJsonp;window.webpackJsonp=function(o,c){for(var p,s,l=0,i=[];l<o.length;l++)s=o[l],a[s]&&i.push.apply(i,a[s]),a[s]=0;for(p in c)e[p]=c[p];for(n&&n(o,c);i.length;)i.shift().call(null,t);if(c[0])return r[0]=0,t(0)};var r={},a={0:0};t.e=function(e,n){if(0===a[e])return n.call(null,t);if(void 0!==a[e])a[e].push(n);else{a[e]=[n];var r=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"d7d8813599feb765b152",2:"d4e0a640b375c4b52997"}[e]+".js",r.appendChild(o)}},t.m=e,t.c=r,t.p="/"}([]);
//# sourceMappingURL=manifest.66d994092e61600982a8.js.map

View file

@ -1,2 +0,0 @@
!function(e){function t(n){if(r[n])return r[n].exports;var a=r[n]={exports:{},id:n,loaded:!1};return e[n].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var n=window.webpackJsonp;window.webpackJsonp=function(c,o){for(var p,s,l=0,d=[];l<c.length;l++)s=c[l],a[s]&&d.push.apply(d,a[s]),a[s]=0;for(p in o)e[p]=o[p];for(n&&n(c,o);d.length;)d.shift().call(null,t);if(o[0])return r[0]=0,t(0)};var r={},a={0:0};t.e=function(e,n){if(0===a[e])return n.call(null,t);if(void 0!==a[e])a[e].push(n);else{a[e]=[n];var r=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.src=t.p+"static/js/"+e+"."+{1:"d7d8813599feb765b152",2:"dcc60205ebdef9eb3d87"}[e]+".js",r.appendChild(c)}},t.m=e,t.c=r,t.p="/"}([]);
//# sourceMappingURL=manifest.da7ea91e505330123f38.js.map

View file

@ -3,7 +3,7 @@ defmodule Pleroma.Builders.ActivityBuilder do
alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.ActivityPub.ActivityPub
def build(data \\ %{}, opts \\ %{}) do def build(data \\ %{}, opts \\ %{}) do
user = opts[:user] || UserBuilder.build user = opts[:user] || Pleroma.Factory.insert(:user)
activity = %{ activity = %{
"id" => 1, "id" => 1,
"actor" => user.ap_id, "actor" => user.ap_id,
@ -29,7 +29,7 @@ defmodule Pleroma.Builders.ActivityBuilder do
end end
def public_and_non_public do def public_and_non_public do
{:ok, user} = UserBuilder.insert user = Pleroma.Factory.insert(:user)
public = build(%{"id" => 1}, %{user: user}) public = build(%{"id" => 1}, %{user: user})
non_public = build(%{"id" => 2, "to" => []}, %{user: user}) non_public = build(%{"id" => 2, "to" => []}, %{user: user})

View file

@ -3,6 +3,8 @@ defmodule Pleroma.UserTest do
alias Pleroma.User alias Pleroma.User
use Pleroma.DataCase use Pleroma.DataCase
import Pleroma.Factory
test "ap_id returns the activity pub id for the user" do test "ap_id returns the activity pub id for the user" do
host = host =
Application.get_env(:pleroma, Pleroma.Web.Endpoint) Application.get_env(:pleroma, Pleroma.Web.Endpoint)
@ -25,21 +27,21 @@ defmodule Pleroma.UserTest do
end end
test "follow takes a user and another user" do test "follow takes a user and another user" do
{ :ok, user } = UserBuilder.insert user = insert(:user)
{ :ok, following } = UserBuilder.insert(%{nickname: "guy"}) followed = insert(:user)
{:ok, user } = User.follow(user, following) {:ok, user } = User.follow(user, followed)
user = Repo.get(User, user.id) user = Repo.get(User, user.id)
assert user.following == [User.ap_followers(following)] assert user.following == [User.ap_followers(followed)]
end end
test "unfollow takes a user and another user" do test "unfollow takes a user and another user" do
{ :ok, following } = UserBuilder.insert(%{nickname: "guy"}) followed = insert(:user)
{ :ok, user } = UserBuilder.insert(%{following: [User.ap_followers(following)]}) user = insert(:user, %{following: [User.ap_followers(followed)]})
{:ok, user } = User.unfollow(user, following) {:ok, user } = User.unfollow(user, followed)
user = Repo.get(User, user.id) user = Repo.get(User, user.id)
@ -47,8 +49,8 @@ defmodule Pleroma.UserTest do
end end
test "test if a user is following another user" do test "test if a user is following another user" do
{ :ok, followed } = UserBuilder.insert(%{nickname: "guy"}) followed = insert(:user)
{ :ok, user } = UserBuilder.insert(%{following: [User.ap_followers(followed)]}) user = insert(:user, %{following: [User.ap_followers(followed)]})
assert User.following?(user, followed) assert User.following?(user, followed)
refute User.following?(followed, user) refute User.following?(followed, user)

File diff suppressed because one or more lines are too long

View file

@ -45,8 +45,11 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
test "an activity" do test "an activity" do
{:ok, user} = UserBuilder.insert {:ok, user} = UserBuilder.insert
{:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"}) # {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
{:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]}) mentioned_user = insert(:user, %{nickname: "shp"})
# {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]})
follower = insert(:user, %{following: [User.ap_followers(user)]})
object = %Object{ object = %Object{
data: %{ data: %{
@ -62,7 +65,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
} }
} }
content_html = "Some content mentioning <a href='shp'>@shp</shp>" content_html = "Some content mentioning <a href='#{mentioned_user.ap_id}'>@shp</shp>"
content = HtmlSanitizeEx.strip_tags(content_html) content = HtmlSanitizeEx.strip_tags(content_html)
date = DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") |> DateTime.to_iso8601 date = DateTime.from_naive!(~N[2016-05-24 13:26:08.003], "Etc/UTC") |> DateTime.to_iso8601

View file

@ -5,13 +5,23 @@ defmodule Pleroma.Web.TwitterAPI.Representers.UserRepresenterTest do
alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter alias Pleroma.Web.TwitterAPI.Representers.UserRepresenter
alias Pleroma.Builders.UserBuilder alias Pleroma.Builders.UserBuilder
import Pleroma.Factory
setup do setup do
{:ok, user} = UserBuilder.insert user = insert(:user)
[user: user] [user: user]
end end
test "A user with an avatar object", %{user: user} do
image = "image"
user = %{ user | avatar: %{ "url" => [%{"href" => image}] }}
represented = UserRepresenter.to_map(user)
assert represented["profile_image_url"] == image
end
test "A user", %{user: user} do test "A user", %{user: user} do
image = "https://placehold.it/48x48" image = "https://placehold.it/48x48"
represented = %{ represented = %{
"id" => user.id, "id" => user.id,
"name" => user.name, "name" => user.name,

View file

@ -94,10 +94,10 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
end end
test "with credentials", %{conn: conn, user: current_user} do test "with credentials", %{conn: conn, user: current_user} do
{:ok, user} = UserBuilder.insert user = insert(:user)
activities = ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user}) activities = ActivityBuilder.insert_list(30, %{"to" => [User.ap_followers(user)]}, %{user: user})
returned_activities = ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user}) returned_activities = ActivityBuilder.insert_list(10, %{"to" => [User.ap_followers(user)]}, %{user: user})
{:ok, other_user} = UserBuilder.insert(%{ap_id: "glimmung", nickname: "nockame"}) other_user = insert(:user)
ActivityBuilder.insert_list(10, %{}, %{user: other_user}) ActivityBuilder.insert_list(10, %{}, %{user: other_user})
since_id = List.last(activities).id since_id = List.last(activities).id
@ -110,7 +110,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200) response = json_response(conn, 200)
assert length(response) == 10 assert length(response) == 10
assert response == Enum.map(returned_activities, fn (activity) -> ActivityRepresenter.to_map(activity, %{user: user, for: current_user}) end) assert response == Enum.map(returned_activities, fn (activity) -> ActivityRepresenter.to_map(activity, %{user: User.get_cached_by_ap_id(activity.data["actor"]), for: current_user}) end)
end end
end end
@ -122,7 +122,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
end end
test "with credentials", %{conn: conn, user: current_user} do test "with credentials", %{conn: conn, user: current_user} do
{:ok, followed } = UserBuilder.insert(%{name: "some guy"}) followed = insert(:user)
conn = conn conn = conn
|> with_credentials(current_user.nickname, "test") |> with_credentials(current_user.nickname, "test")
@ -142,7 +142,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
end end
test "with credentials", %{conn: conn, user: current_user} do test "with credentials", %{conn: conn, user: current_user} do
{:ok, followed } = UserBuilder.insert(%{name: "some guy"}) followed = insert(:user)
{:ok, current_user} = User.follow(current_user, followed) {:ok, current_user} = User.follow(current_user, followed)
assert current_user.following == [User.ap_followers(followed)] assert current_user.following == [User.ap_followers(followed)]
@ -157,6 +157,24 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
end end
end end
describe "POST /api/qvitter/update_avatar.json" do
setup [:valid_user]
test "without valid credentials", %{conn: conn} do
conn = post conn, "/api/qvitter/update_avatar.json"
assert json_response(conn, 403) == %{"error" => "Invalid credentials."}
end
test "with credentials", %{conn: conn, user: current_user} do
conn = conn
|> with_credentials(current_user.nickname, "test")
|> post("/api/qvitter/update_avatar.json", %{img: Pleroma.Web.ActivityPub.ActivityPubTest.data_uri})
current_user = Repo.get(User, current_user.id)
assert is_map(current_user.avatar)
assert json_response(conn, 200) == UserRepresenter.to_map(current_user, %{for: current_user})
end
end
describe "POST /api/favorites/create/:id" do describe "POST /api/favorites/create/:id" do
setup [:valid_user] setup [:valid_user]
test "without valid credentials", %{conn: conn} do test "without valid credentials", %{conn: conn} do

View file

@ -78,7 +78,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
test "fetch public statuses" do test "fetch public statuses" do
%{ public: activity, user: user } = ActivityBuilder.public_and_non_public %{ public: activity, user: user } = ActivityBuilder.public_and_non_public
{:ok, follower } = UserBuilder.insert(%{name: "dude", ap_id: "idididid", following: [User.ap_followers(user)]})
follower = insert(:user, following: [User.ap_followers(user)])
statuses = TwitterAPI.fetch_public_statuses(follower) statuses = TwitterAPI.fetch_public_statuses(follower)
@ -87,19 +88,18 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end end
test "fetch friends' statuses" do test "fetch friends' statuses" do
ActivityBuilder.public_and_non_public user = insert(:user, %{following: ["someguy/followers"]})
{:ok, activity} = ActivityBuilder.insert(%{"to" => ["someguy/followers"]}) {:ok, activity} = ActivityBuilder.insert(%{"to" => ["someguy/followers"]})
{:ok, direct_activity} = ActivityBuilder.insert(%{"to" => ["some other id"]}) {:ok, direct_activity} = ActivityBuilder.insert(%{"to" => [user.ap_id]})
{:ok, user} = UserBuilder.insert(%{ap_id: "some other id", following: ["someguy/followers"]})
statuses = TwitterAPI.fetch_friend_statuses(user) statuses = TwitterAPI.fetch_friend_statuses(user)
activity_user = Repo.get_by(User, ap_id: activity.data["actor"]) activity_user = Repo.get_by(User, ap_id: activity.data["actor"])
direct_activity_user = Repo.get_by(User, ap_id: direct_activity.data["actor"])
assert length(statuses) == 2 assert length(statuses) == 2
assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: activity_user}) assert Enum.at(statuses, 0) == ActivityRepresenter.to_map(activity, %{user: activity_user})
assert Enum.at(statuses, 1) == ActivityRepresenter.to_map(direct_activity, %{user: activity_user, mentioned: [user]}) assert Enum.at(statuses, 1) == ActivityRepresenter.to_map(direct_activity, %{user: direct_activity_user, mentioned: [user]})
end end
test "fetch a single status" do test "fetch a single status" do
@ -113,8 +113,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end end
test "Follow another user" do test "Follow another user" do
{ :ok, user } = UserBuilder.insert user = insert(:user)
{ :ok, following } = UserBuilder.insert(%{nickname: "guy"}) following = insert(:user)
{:ok, user, following, activity } = TwitterAPI.follow(user, following.id) {:ok, user, following, activity } = TwitterAPI.follow(user, following.id)
@ -126,8 +126,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end end
test "Unfollow another user using user_id" do test "Unfollow another user using user_id" do
{ :ok, following } = UserBuilder.insert(%{nickname: "guy"}) following = insert(:user)
{ :ok, user } = UserBuilder.insert(%{following: [User.ap_followers(following)]}) user = insert(:user, %{following: [User.ap_followers(following)]})
{:ok, user, _following } = TwitterAPI.unfollow(user, %{"user_id" => following.id}) {:ok, user, _following } = TwitterAPI.unfollow(user, %{"user_id" => following.id})
@ -137,8 +137,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end end
test "Unfollow another user using screen_name" do test "Unfollow another user using screen_name" do
{ :ok, following } = UserBuilder.insert(%{nickname: "guy"}) following = insert(:user)
{ :ok, user } = UserBuilder.insert(%{following: [User.ap_followers(following)]}) user = insert(:user, %{following: [User.ap_followers(following)]})
{:ok, user, _following } = TwitterAPI.unfollow(user, %{"screen_name" => following.nickname}) {:ok, user, _following } = TwitterAPI.unfollow(user, %{"screen_name" => following.nickname})
@ -171,8 +171,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
test "it can parse mentions and return the relevant users" do test "it can parse mentions and return the relevant users" do
text = "@gsimg According to @archaeme , that is @daggsy." text = "@gsimg According to @archaeme , that is @daggsy."
{:ok, gsimg} = UserBuilder.insert(%{nickname: "gsimg"}) gsimg = insert(:user, %{nickname: "gsimg"})
{:ok, archaeme} = UserBuilder.insert(%{nickname: "archaeme"}) archaeme = insert(:user, %{nickname: "archaeme"})
expected_result = [ expected_result = [
{"@gsimg", gsimg}, {"@gsimg", gsimg},
@ -185,11 +185,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
test "it adds user links to an existing text" do test "it adds user links to an existing text" do
text = "@gsimg According to @archaeme , that is @daggsy." text = "@gsimg According to @archaeme , that is @daggsy."
{:ok, _gsimg} = UserBuilder.insert(%{nickname: "gsimg", ap_id: "first_link" }) gsimg = insert(:user, %{nickname: "gsimg"})
{:ok, _archaeme} = UserBuilder.insert(%{nickname: "archaeme", ap_id: "second_link"}) archaeme = insert(:user, %{nickname: "archaeme"})
mentions = TwitterAPI.parse_mentions(text) mentions = TwitterAPI.parse_mentions(text)
expected_text = "<a href='first_link'>@gsimg</a> According to <a href='second_link'>@archaeme</a> , that is @daggsy." expected_text = "<a href='#{gsimg.ap_id}'>@gsimg</a> According to <a href='#{archaeme.ap_id}'>@archaeme</a> , that is @daggsy."
assert TwitterAPI.add_user_links(text, mentions) == expected_text assert TwitterAPI.add_user_links(text, mentions) == expected_text
end end