diff options
author | lambda <pleromagit@rogerbraun.net> | 2018-08-12 12:04:15 +0000 |
---|---|---|
committer | lambda <pleromagit@rogerbraun.net> | 2018-08-12 12:04:15 +0000 |
commit | 13440a80e1e30141f0f0466ff351bd6f9c148228 (patch) | |
tree | 5e58e60026c956026f7cb7712cbee1a30e60838b /lib | |
parent | 9de614573754c9a1ae9d1b58399fafcc78ee5286 (diff) | |
parent | 1e9d152d608c83c906ed9a4ca2c6a21d644e2728 (diff) | |
download | pleroma-13440a80e1e30141f0f0466ff351bd6f9c148228.tar.gz |
Merge branch 'feature/invites' into 'develop'
Invites
Closes #108
See merge request pleroma/pleroma!208
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mix/tasks/generate_invite_token.ex | 25 | ||||
-rw-r--r-- | lib/pleroma/user_invite_token.ex | 40 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 9 | ||||
-rw-r--r-- | lib/pleroma/web/twitter_api/twitter_api.ex | 39 |
4 files changed, 100 insertions, 13 deletions
diff --git a/lib/mix/tasks/generate_invite_token.ex b/lib/mix/tasks/generate_invite_token.ex new file mode 100644 index 000000000..c4daa9a6c --- /dev/null +++ b/lib/mix/tasks/generate_invite_token.ex @@ -0,0 +1,25 @@ +defmodule Mix.Tasks.GenerateInviteToken do + use Mix.Task + + @shortdoc "Generate invite token for user" + def run([]) do + Mix.Task.run("app.start") + + with {:ok, token} <- Pleroma.UserInviteToken.create_token() do + IO.puts("Generated user invite token") + + IO.puts( + "Url: #{ + Pleroma.Web.Router.Helpers.redirect_url( + Pleroma.Web.Endpoint, + :registration_page, + token.token + ) + }" + ) + else + _ -> + IO.puts("Error creating token") + end + end +end diff --git a/lib/pleroma/user_invite_token.ex b/lib/pleroma/user_invite_token.ex new file mode 100644 index 000000000..48ee1019a --- /dev/null +++ b/lib/pleroma/user_invite_token.ex @@ -0,0 +1,40 @@ +defmodule Pleroma.UserInviteToken do + use Ecto.Schema + + import Ecto.Changeset + + alias Pleroma.{User, UserInviteToken, Repo} + + schema "user_invite_tokens" do + field(:token, :string) + field(:used, :boolean, default: false) + + timestamps() + end + + def create_token do + token = :crypto.strong_rand_bytes(32) |> Base.url_encode64() + + token = %UserInviteToken{ + used: false, + token: token + } + + Repo.insert(token) + end + + def used_changeset(struct) do + struct + |> cast(%{}, []) + |> put_change(:used, true) + end + + def mark_as_used(token) do + with %{used: false} = token <- Repo.get_by(UserInviteToken, %{token: token}), + {:ok, token} <- Repo.update(used_changeset(token)) do + {:ok, token} + else + _e -> {:error, token} + end + end +end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index fc7a947aa..be0c10ea4 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -202,9 +202,7 @@ defmodule Pleroma.Web.Router do get("/statuses/show/:id", TwitterAPI.Controller, :fetch_status) get("/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation) - if @registrations_open do - post("/account/register", TwitterAPI.Controller, :register) - end + post("/account/register", TwitterAPI.Controller, :register) get("/search", TwitterAPI.Controller, :search) get("/statusnet/tags/timeline/:tag", TwitterAPI.Controller, :public_and_external_timeline) @@ -356,6 +354,7 @@ defmodule Pleroma.Web.Router do end scope "/", Fallback do + get("/registration/:token", RedirectController, :registration_page) get("/*path", RedirectController, :redirector) end end @@ -370,4 +369,8 @@ defmodule Fallback.RedirectController do |> send_file(200, "priv/static/index.html") end end + + def registration_page(conn, params) do + redirector(conn, params) + end end diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index c23b3c2c4..9d8815ce7 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -1,11 +1,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do - alias Pleroma.{User, Activity, Repo, Object} + alias Pleroma.{UserInviteToken, User, Activity, Repo, Object} alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.Web.TwitterAPI.UserView alias Pleroma.Web.{OStatus, CommonAPI} import Ecto.Query + @instance Application.get_env(:pleroma, :instance) @httpoison Application.get_env(:pleroma, :httpoison) + @registrations_open Keyword.get(@instance, :registrations_open) def create_status(%User{} = user, %{"status" => _} = data) do CommonAPI.post(user, data) @@ -120,6 +122,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do end def register_user(params) do + tokenString = params["token"] + params = %{ nickname: params["nickname"], name: params["fullname"], @@ -129,17 +133,32 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do password_confirmation: params["confirm"] } - changeset = User.register_changeset(%User{}, params) + # no need to query DB if registration is open + unless @registrations_open || is_nil(tokenString) do + token = Repo.get_by(UserInviteToken, %{token: tokenString}) + end - with {:ok, user} <- Repo.insert(changeset) do - {:ok, user} - else - {:error, changeset} -> - errors = - Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end) - |> Jason.encode!() + cond do + @registrations_open || (!is_nil(token) && !token.used) -> + changeset = User.register_changeset(%User{}, params) + + with {:ok, user} <- Repo.insert(changeset) do + !@registrations_open && UserInviteToken.mark_as_used(token.token) + {:ok, user} + else + {:error, changeset} -> + errors = + Ecto.Changeset.traverse_errors(changeset, fn {msg, _opts} -> msg end) + |> Jason.encode!() + + {:error, %{error: errors}} + end + + !@registrations_open && is_nil(token) -> + {:error, "Invalid token"} - {:error, %{error: errors}} + !@registrations_open && token.used -> + {:error, "Expired token"} end end |