forked from potsda.mn/mobilizon
Introduce avatar and banner and fetch Gravatar to fill avatar during registration
Signed-off-by: Thomas Citharel <tcit@tcit.fr> typo Signed-off-by: Thomas Citharel <tcit@tcit.fr> Rename avatar to avatar_url, same with header. Add a comment to explain why the tweak with HTTPoison and TLS1.2 Signed-off-by: Thomas Citharel <tcit@tcit.fr> Rename avatar to avatar_url Signed-off-by: Thomas Citharel <tcit@tcit.fr> rename old avatar properties in front-end to avatar_url Signed-off-by: Thomas Citharel <tcit@tcit.fr> fix change gravatar from ?d= to ?default= Signed-off-by: Thomas Citharel <tcit@tcit.fr> reorganize aliases and imports Signed-off-by: Thomas Citharel <tcit@tcit.fr> set avatar url only when gravatar exists, add a test for that case Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
35492570de
commit
4b4ecec693
|
@ -20,13 +20,13 @@
|
|||
<v-spacer></v-spacer>
|
||||
<div class="text-xs-center">
|
||||
<v-avatar size="125px">
|
||||
<img v-if="!account.avatarRemoteUrl"
|
||||
<img v-if="!account.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="account.avatarRemoteUrl"
|
||||
:src="account.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
</div>
|
||||
|
|
|
@ -42,13 +42,13 @@
|
|||
<v-flex xs2>
|
||||
<router-link :to="{name: 'Account', params: {'id': event.organizer.id}}">
|
||||
<v-avatar size="75px">
|
||||
<img v-if="!event.organizer.avatarRemoteUrl"
|
||||
<img v-if="!event.organizer.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="event.organizer.avatarRemoteUrl"
|
||||
:src="event.organizer.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
|
@ -57,13 +57,13 @@
|
|||
<v-flex xs2 v-for="account in event.participants" :key="account.id">
|
||||
<router-link :to="{name: 'Account', params: {'id': account.id}}">
|
||||
<v-avatar size="75px">
|
||||
<img v-if="!account.avatarRemoteUrl"
|
||||
<img v-if="!account.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="account.avatarRemoteUrl"
|
||||
:src="account.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
</router-link>
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
<v-spacer></v-spacer>
|
||||
<div class="text-xs-center">
|
||||
<v-avatar size="125px">
|
||||
<img v-if="!group.avatarRemoteUrl"
|
||||
<img v-if="!group.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="group.avatarRemoteUrl"
|
||||
:src="group.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
<v-card-title class="pl-5 pt-5">
|
||||
|
@ -77,13 +77,13 @@
|
|||
<v-badge overlap>
|
||||
<span slot="badge" v-if="member.role == 3"><v-icon>stars</v-icon></span>
|
||||
<v-avatar size="75px">
|
||||
<img v-if="!member.account.avatarRemoteUrl"
|
||||
<img v-if="!member.account.avatar_url"
|
||||
class="img-circle elevation-7 mb-1"
|
||||
src="http://lorempixel.com/125/125/"
|
||||
>
|
||||
<img v-else
|
||||
class="img-circle elevation-7 mb-1"
|
||||
:src="member.account.avatarRemoteUrl"
|
||||
:src="member.account.avatar_url"
|
||||
>
|
||||
</v-avatar>
|
||||
</v-badge>
|
||||
|
|
|
@ -18,6 +18,8 @@ defmodule Eventos.Accounts.Account do
|
|||
field :uri, :string
|
||||
field :url, :string
|
||||
field :username, :string
|
||||
field :avatar_url, :string
|
||||
field :banner_url, :string
|
||||
has_many :organized_events, Event, [foreign_key: :organizer_account_id]
|
||||
many_to_many :groups, Group, join_through: Member
|
||||
has_many :group_request, Request
|
||||
|
@ -29,14 +31,14 @@ defmodule Eventos.Accounts.Account do
|
|||
@doc false
|
||||
def changeset(%Account{} = account, attrs) do
|
||||
account
|
||||
|> cast(attrs, [:username, :domain, :display_name, :description, :private_key, :public_key, :suspended, :uri, :url])
|
||||
|> cast(attrs, [:username, :domain, :display_name, :description, :private_key, :public_key, :suspended, :uri, :url, :avatar_url, :banner_url])
|
||||
|> validate_required([:username, :public_key, :suspended, :uri, :url])
|
||||
|> unique_constraint(:username, name: :accounts_username_domain_index)
|
||||
end
|
||||
|
||||
def registration_changeset(%Account{} = account, attrs) do
|
||||
account
|
||||
|> cast(attrs, [:username, :domain, :display_name, :description, :private_key, :public_key, :suspended, :uri, :url])
|
||||
|> cast(attrs, [:username, :domain, :display_name, :description, :private_key, :public_key, :suspended, :uri, :url, :avatar_url, :banner_url])
|
||||
|> validate_required([:username, :public_key, :suspended, :uri, :url])
|
||||
|> unique_constraint(:username)
|
||||
end
|
||||
|
|
|
@ -4,8 +4,9 @@ defmodule Eventos.Accounts do
|
|||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Eventos.Repo
|
||||
import Exgravatar
|
||||
|
||||
alias Eventos.Repo
|
||||
alias Eventos.Accounts.Account
|
||||
|
||||
@doc """
|
||||
|
@ -173,6 +174,19 @@ defmodule Eventos.Accounts do
|
|||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Fetch gravatar url for email and set it as avatar if it exists
|
||||
"""
|
||||
defp gravatar(email) do
|
||||
url = gravatar_url(email, default: "404")
|
||||
case HTTPoison.get(url, [], [ssl: [{:versions, [:'tlsv1.2']}]]) do # See https://github.com/edgurgel/httpoison#note-about-broken-ssl-in-erlang-19
|
||||
{:ok, %HTTPoison.Response{status_code: 200}} ->
|
||||
url
|
||||
_ -> # User doesn't have a gravatar email, or other issues
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Register user
|
||||
"""
|
||||
|
@ -180,13 +194,15 @@ defmodule Eventos.Accounts do
|
|||
{:ok, {privkey, pubkey}} = RsaEx.generate_keypair("4096")
|
||||
|
||||
|
||||
avatar = gravatar(email)
|
||||
account = Eventos.Accounts.Account.registration_changeset(%Eventos.Accounts.Account{}, %{
|
||||
username: username,
|
||||
domain: nil,
|
||||
private_key: privkey,
|
||||
public_key: pubkey,
|
||||
uri: "h",
|
||||
url: "h"
|
||||
url: "h",
|
||||
avatar_url: avatar,
|
||||
})
|
||||
|
||||
user = Eventos.Accounts.User.registration_changeset(%Eventos.Accounts.User{}, %{
|
||||
|
@ -207,7 +223,6 @@ defmodule Eventos.Accounts do
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
@doc """
|
||||
Creates a user.
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ defmodule Eventos.Accounts.User do
|
|||
import Ecto.Changeset
|
||||
alias Eventos.Accounts.{Account, User}
|
||||
|
||||
|
||||
schema "users" do
|
||||
field :email, :string
|
||||
field :password_hash, :string
|
||||
|
@ -31,9 +30,12 @@ defmodule Eventos.Accounts.User do
|
|||
|> changeset(params)
|
||||
|> cast(params, ~w(password)a, [])
|
||||
|> validate_length(:password, min: 6, max: 100)
|
||||
|> hash_password
|
||||
|> hash_password()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Hash password when it's changed
|
||||
"""
|
||||
defp hash_password(changeset) do
|
||||
case changeset do
|
||||
%Ecto.Changeset{valid?: true,
|
||||
|
@ -45,5 +47,4 @@ defmodule Eventos.Accounts.User do
|
|||
changeset
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -27,6 +27,8 @@ defmodule EventosWeb.AccountView do
|
|||
suspended: account.suspended,
|
||||
uri: account.uri,
|
||||
url: account.url,
|
||||
avatar_url: account.avatar_url,
|
||||
banner_url: account.banner_url,
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -40,6 +42,8 @@ defmodule EventosWeb.AccountView do
|
|||
suspended: account.suspended,
|
||||
uri: account.uri,
|
||||
url: account.url,
|
||||
avatar_url: account.avatar_url,
|
||||
banner_url: account.banner_url,
|
||||
organized_events: render_many(account.organized_events, EventView, "event_simple.json")
|
||||
}
|
||||
end
|
||||
|
|
7
mix.exs
7
mix.exs
|
@ -44,7 +44,6 @@ defmodule Eventos.Mixfile do
|
|||
{:phoenix_ecto, "~> 3.2"},
|
||||
{:postgrex, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 2.10"},
|
||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||
{:gettext, "~> 0.11"},
|
||||
{:cowboy, "~> 1.0"},
|
||||
{:guardian, "~> 1.0"},
|
||||
|
@ -58,10 +57,14 @@ defmodule Eventos.Mixfile do
|
|||
{:geo_postgis, "~> 1.0"},
|
||||
{:timex, "~> 3.0"},
|
||||
{:timex_ecto, "~> 3.0"},
|
||||
{:icalendar, "~> 0.6"},
|
||||
{:exgravatar, "~> 2.0.1"},
|
||||
{:httpoison, "~> 1.0"},
|
||||
# Dev and test dependencies
|
||||
{:phoenix_live_reload, "~> 1.0", only: :dev},
|
||||
{:ex_machina, "~> 2.1", only: :test},
|
||||
{:credo, "~> 0.8", only: [:dev, :test], runtime: false},
|
||||
{:excoveralls, "~> 0.8", only: :test},
|
||||
{:icalendar, "~> 0.6"},
|
||||
{:ex_doc, "~> 0.16", only: :dev, runtime: false},
|
||||
{:mix_test_watch, "~> 0.5", only: :dev, runtime: false},
|
||||
{:ex_unit_notifier, "~> 0.1", only: :test}
|
||||
|
|
8
mix.lock
8
mix.lock
|
@ -1,4 +1,5 @@
|
|||
%{"argon2_elixir": {:hex, :argon2_elixir, "1.2.14", "0fc4bfbc1b7e459954987d3d2f3836befd72d63f3a355e3978f5005dd6e80816", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
%{
|
||||
"argon2_elixir": {:hex, :argon2_elixir, "1.2.14", "0fc4bfbc1b7e459954987d3d2f3836befd72d63f3a355e3978f5005dd6e80816", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"base64url": {:hex, :base64url, "0.0.1", "36a90125f5948e3afd7be97662a1504b934dd5dac78451ca6e9abf85a10286be", [:rebar], [], "hexpm"},
|
||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [], [], "hexpm"},
|
||||
"certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [], [], "hexpm"},
|
||||
|
@ -21,6 +22,7 @@
|
|||
"ex_machina": {:hex, :ex_machina, "2.1.0", "4874dc9c78e7cf2d429f24dc3c4005674d4e4da6a08be961ffccc08fb528e28b", [], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"ex_unit_notifier": {:hex, :ex_unit_notifier, "0.1.4", "36a2dcab829f506e01bf17816590680dd1474407926d43e64c1263e627c364b8", [], [], "hexpm"},
|
||||
"excoveralls": {:hex, :excoveralls, "0.8.0", "99d2691d3edf8612f128be3f9869c4d44b91c67cec92186ce49470ae7a7404cf", [], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"exgravatar": {:hex, :exgravatar, "2.0.1", "66d595c7d63dd6bbac442c5542a724375ae29144059c6fe093e61553850aace4", [], [], "hexpm"},
|
||||
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"file_system": {:hex, :file_system, "0.2.2", "7f1e9de4746f4eb8a4ca8f2fbab582d84a4e40fa394cce7bfcb068b988625b06", [:mix], [], "hexpm"},
|
||||
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], [], "hexpm"},
|
||||
|
@ -30,6 +32,7 @@
|
|||
"guardian": {:hex, :guardian, "1.0.1", "db0fbaf571c3b874785818b7272eaf5f1ed97a2f9b1f8bc5dc8b0fb8f8f7bb06", [:mix], [{:jose, "~> 1.8", [hex: :jose, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2 or ~> 1.3", [hex: :phoenix, repo: "hexpm", optional: true]}, {:plug, "~> 1.3.3 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}, {:uuid, ">= 1.1.1", [hex: :uuid, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"guardian_db": {:hex, :guardian_db, "1.1.0", "45ab94206cce38f7443dc27de6dc52966ccbdeff65ca1b1f11a6d8f3daceb556", [], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:guardian, "~> 1.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"httpoison": {:hex, :httpoison, "1.0.0", "1f02f827148d945d40b24f0b0a89afe40bfe037171a6cf70f2486976d86921cd", [], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"icalendar": {:hex, :icalendar, "0.6.0", "0e30054b234752fa1ec3e2b928101f8c98f70067766590360d7790b41faab315", [], [{:timex, "~> 3.0", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"jose": {:hex, :jose, "1.8.4", "7946d1e5c03a76ac9ef42a6e6a20001d35987afd68c2107bcd8f01a84e75aa73", [:mix, :rebar3], [{:base64url, "~> 0.0.1", [hex: :base64url, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
|
@ -57,4 +60,5 @@
|
|||
"timex_ecto": {:hex, :timex_ecto, "3.2.1", "461140751026e1ca03298fab628f78ab189e78784175f5e301eefa034ee530aa", [], [{:ecto, "~> 2.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"tzdata": {:hex, :tzdata, "0.5.14", "56f05ea3dd87db946966ab3c7168c0b35025c7ee0e9b4fc130a04631f5611eb1", [], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [], [], "hexpm"},
|
||||
"uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm"}}
|
||||
"uuid": {:hex, :uuid, "1.1.8", "e22fc04499de0de3ed1116b770c7737779f226ceefa0badb3592e64d5cfb4eb9", [:mix], [], "hexpm"},
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
defmodule Eventos.Repo.Migrations.AddAvatarAndBannerToAccount do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:accounts) do
|
||||
add :avatar_url, :string, null: true
|
||||
add :banner_url, :string, null: true
|
||||
end
|
||||
end
|
||||
end
|
|
@ -32,14 +32,23 @@ defmodule EventosWeb.UserControllerTest do
|
|||
describe "create user" do
|
||||
test "renders user when data is valid", %{conn: conn} do
|
||||
conn = post conn, user_path(conn, :create), @create_attrs
|
||||
assert %{"user" => %{"id" => id}} = json_response(conn, 201)
|
||||
assert %{"user" => %{"id" => id, "account" => %{"avatar_url" => avatar_url}}} = json_response(conn, 201)
|
||||
assert id > 0
|
||||
assert avatar_url == nil
|
||||
end
|
||||
|
||||
test "renders errors when data is invalid", %{conn: conn} do
|
||||
conn = post conn, user_path(conn, :create), @invalid_attrs
|
||||
assert json_response(conn, 400)["msg"] != %{}
|
||||
end
|
||||
|
||||
test "renders user with avatar when email is valid", %{conn: conn} do
|
||||
attrs = %{email: "contact@framasoft.org", password: "some password_hash", username: "framasoft"}
|
||||
conn = post conn, user_path(conn, :create), attrs
|
||||
assert %{"user" => %{"id" => id, "account" => %{"avatar_url" => avatar_url}}} = json_response(conn, 201)
|
||||
assert id > 0
|
||||
assert avatar_url == "https://secure.gravatar.com/avatar/68b2910a6bb84a482d920e1057533100?default=404"
|
||||
end
|
||||
end
|
||||
|
||||
# describe "update user" do
|
||||
|
|
Loading…
Reference in a new issue